From 6250397ac8a7a23fb41c726b9555d93ead0f1dc8 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 12 Jun 2014 11:44:31 +1000 Subject: [PATCH] udev: split libinput_udev context init into two functions This is preparation work for context-specific log handlers. Callers are now encouraged to first initialize the context with libinput_udev_create_context() and then set the seat for this context with libinput_udev_assign_seat(). In the upcoming patch to support context-specific log handlers this enables a caller to set the log handler for a context before any devices are initialized. Otherwise, a log message generated by a new device may pass a libinput context that the caller is not yet aware of. Signed-off-by: Peter Hutterer Reviewed-by: Hans de Goede --- doc/libinput.doxygen.in | 3 ++- src/libinput.h | 51 ++++++++++++++++++++++++++++++++++++++++++- src/udev-seat.c | 58 ++++++++++++++++++++++++++++++++++++++++--------- test/udev.c | 48 ++++++++++++++++++++++------------------ tools/event-debug.c | 8 ++++++- tools/event-gui.c | 4 ++-- 6 files changed, 136 insertions(+), 36 deletions(-) diff --git a/doc/libinput.doxygen.in b/doc/libinput.doxygen.in index f78b7cf..9f931c3 100644 --- a/doc/libinput.doxygen.in +++ b/doc/libinput.doxygen.in @@ -1570,7 +1570,8 @@ INCLUDE_FILE_PATTERNS = # undefined via #undef or recursively expanded use the := operator # instead of the = operator. -PREDEFINED = LIBINPUT_ATTRIBUTE_PRINTF(f,a)= +PREDEFINED = LIBINPUT_ATTRIBUTE_PRINTF(f, a)= \ + LIBINPUT_ATTRIBUTE_DEPRECATED # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. diff --git a/src/libinput.h b/src/libinput.h index fb2e490..678e49d 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -33,6 +33,7 @@ extern "C" { #define LIBINPUT_ATTRIBUTE_PRINTF(_format, _args) \ __attribute__ ((format (printf, _format, _args))) +#define LIBINPUT_ATTRIBUTE_DEPRECATED __attribute__ ((deprecated)) /** * @mainpage @@ -782,6 +783,49 @@ struct libinput_interface { /** * @ingroup base * + * Create a new libinput context from udev. This context is inactive until + * assigned a seat ID with libinput_udev_assign_seat(). + * + * @param interface The callback interface + * @param user_data Caller-specific data passed to the various callback + * interfaces. + * @param udev An already initialized udev context + * + * @return An initialized, but inactive libinput context or NULL on error + */ +struct libinput * +libinput_udev_create_context(const struct libinput_interface *interface, + void *user_data, + struct udev *udev); + +/** + * @ingroup base + * + * Assign a seat to this libinput context. New devices or the removal of + * existing devices will appear as events during libinput_dispatch(). + * + * libinput_udev_assign_seat() succeeds even if no input devices are currently + * available on this seat, or if devices are available but fail to open in + * @ref libinput_interface::open_restricted. Devices that do not have the + * minimum capabilities to be recognized as pointer, keyboard or touch + * device are ignored. Such devices and those that failed to open + * ignored until the next call to libinput_resume(). + * + * This function may only be called once per context. + * + * @param libinput A libinput context initialized with + * libinput_udev_create_context() + * @param seat_id A seat identifier. This string must not be NULL. + * + * @return 0 on success or -1 on failure. + */ +int +libinput_udev_assign_seat(struct libinput *libinput, + const char *seat_id); + +/** + * @ingroup base + * * Create a new libinput context from udev, for input devices matching * the given seat ID. New devices or devices removed will appear as events * during libinput_dispatch. @@ -801,12 +845,17 @@ struct libinput_interface { * * @return An initialized libinput context, ready to handle events or NULL on * error. + * + * @deprecated This function was deprecated in 0.4.0 and will be removed + * soon. Use libinput_udev_create_context() and libinput_udev_assign_seat() + * instead. */ struct libinput * libinput_udev_create_for_seat(const struct libinput_interface *interface, void *user_data, struct udev *udev, - const char *seat_id); + const char *seat_id) + LIBINPUT_ATTRIBUTE_DEPRECATED; /** * @ingroup base diff --git a/src/udev-seat.c b/src/udev-seat.c index 38a13b7..89160ff 100644 --- a/src/udev-seat.c +++ b/src/udev-seat.c @@ -333,14 +333,13 @@ static const struct libinput_interface_backend interface_backend = { }; LIBINPUT_EXPORT struct libinput * -libinput_udev_create_for_seat(const struct libinput_interface *interface, - void *user_data, - struct udev *udev, - const char *seat_id) +libinput_udev_create_context(const struct libinput_interface *interface, + void *user_data, + struct udev *udev) { struct udev_input *input; - if (!interface || !udev || !seat_id) + if (!interface || !udev) return NULL; input = zalloc(sizeof *input); @@ -354,14 +353,53 @@ libinput_udev_create_for_seat(const struct libinput_interface *interface, } input->udev = udev_ref(udev); + + return &input->base; +} + +LIBINPUT_EXPORT int +libinput_udev_assign_seat(struct libinput *libinput, + const char *seat_id) +{ + struct udev_input *input = (struct udev_input*)libinput; + + if (!seat_id) + return -1; + if (input->seat_id != NULL) + return -1; + + if (libinput->interface_backend != &interface_backend) { + log_bug_client("Mismatching backends.\n"); + return -1; + } + input->seat_id = strdup(seat_id); - if (udev_input_enable(&input->base) < 0) { - udev_unref(udev); - libinput_destroy(&input->base); - free(input); + if (udev_input_enable(&input->base) < 0) + return -1; + + return 0; +} + +LIBINPUT_EXPORT struct libinput * +libinput_udev_create_for_seat(const struct libinput_interface *interface, + void *user_data, + struct udev *udev, + const char *seat_id) +{ + struct libinput *libinput; + + if (!interface || !udev || !seat_id) return NULL; + + libinput = libinput_udev_create_context(interface, user_data, udev); + if (!libinput) + return NULL; + + if (libinput_udev_assign_seat(libinput, seat_id) != 0) { + libinput_destroy(libinput); + libinput = NULL; } - return &input->base; + return libinput; } diff --git a/test/udev.c b/test/udev.c index 6af2cb0..d13c6e2 100644 --- a/test/udev.c +++ b/test/udev.c @@ -52,26 +52,24 @@ START_TEST(udev_create_NULL) { struct libinput *li; const struct libinput_interface interface; - struct udev *udev = (struct udev*)0xdeadbeef; - const char *seat = (const char*)0xdeaddead; + struct udev *udev; - li = libinput_udev_create_for_seat(NULL, NULL, NULL, NULL); - ck_assert(li == NULL); + udev = udev_new(); - li = libinput_udev_create_for_seat(&interface, NULL, NULL, NULL); - ck_assert(li == NULL); - li = libinput_udev_create_for_seat(NULL, NULL, udev, NULL); - ck_assert(li == NULL); - li = libinput_udev_create_for_seat(NULL, NULL, NULL, seat); + li = libinput_udev_create_context(NULL, NULL, NULL); ck_assert(li == NULL); - li = libinput_udev_create_for_seat(&interface, NULL, udev, NULL); - ck_assert(li == NULL); - li = libinput_udev_create_for_seat(NULL, NULL, udev, seat); + li = libinput_udev_create_context(&interface, NULL, NULL); ck_assert(li == NULL); - li = libinput_udev_create_for_seat(&interface, NULL, NULL, seat); + li = libinput_udev_create_context(NULL, NULL, udev); ck_assert(li == NULL); + + li = libinput_udev_create_context(&interface, NULL, udev); + ck_assert(li != NULL); + ck_assert_int_eq(libinput_udev_assign_seat(li, NULL), -1); + libinput_destroy(li); + udev_unref(udev); } END_TEST @@ -85,8 +83,9 @@ START_TEST(udev_create_seat0) udev = udev_new(); ck_assert(udev != NULL); - li = libinput_udev_create_for_seat(&simple_interface, NULL, udev, "seat0"); + li = libinput_udev_create_context(&simple_interface, NULL, udev); ck_assert(li != NULL); + ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0); fd = libinput_get_fd(li); ck_assert_int_ge(fd, 0); @@ -113,8 +112,9 @@ START_TEST(udev_create_empty_seat) ck_assert(udev != NULL); /* expect a libinput reference, but no events */ - li = libinput_udev_create_for_seat(&simple_interface, NULL, udev, "seatdoesntexist"); + li = libinput_udev_create_context(&simple_interface, NULL, udev); ck_assert(li != NULL); + ck_assert_int_eq(libinput_udev_assign_seat(li, "seatdoesntexist"), 0); fd = libinput_get_fd(li); ck_assert_int_ge(fd, 0); @@ -147,8 +147,9 @@ START_TEST(udev_added_seat_default) udev = udev_new(); ck_assert(udev != NULL); - li = libinput_udev_create_for_seat(&simple_interface, NULL, udev, "seat0"); + li = libinput_udev_create_context(&simple_interface, NULL, udev); ck_assert(li != NULL); + ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0); libinput_dispatch(li); while (!default_seat_found && (event = libinput_get_event(li))) { @@ -184,8 +185,9 @@ START_TEST(udev_double_suspend) udev = udev_new(); ck_assert(udev != NULL); - li = libinput_udev_create_for_seat(&simple_interface, NULL, udev, "seat0"); + li = libinput_udev_create_context(&simple_interface, NULL, udev); ck_assert(li != NULL); + ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0); fd = libinput_get_fd(li); ck_assert_int_ge(fd, 0); @@ -215,8 +217,9 @@ START_TEST(udev_double_resume) udev = udev_new(); ck_assert(udev != NULL); - li = libinput_udev_create_for_seat(&simple_interface, NULL, udev, "seat0"); + li = libinput_udev_create_context(&simple_interface, NULL, udev); ck_assert(li != NULL); + ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0); fd = libinput_get_fd(li); ck_assert_int_ge(fd, 0); @@ -266,8 +269,9 @@ START_TEST(udev_suspend_resume) udev = udev_new(); ck_assert(udev != NULL); - li = libinput_udev_create_for_seat(&simple_interface, NULL, udev, "seat0"); + li = libinput_udev_create_context(&simple_interface, NULL, udev); ck_assert(li != NULL); + ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0); fd = libinput_get_fd(li); ck_assert_int_ge(fd, 0); @@ -305,8 +309,9 @@ START_TEST(udev_device_sysname) udev = udev_new(); ck_assert(udev != NULL); - li = libinput_udev_create_for_seat(&simple_interface, NULL, udev, "seat0"); + li = libinput_udev_create_context(&simple_interface, NULL, udev); ck_assert(li != NULL); + ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0); libinput_dispatch(li); @@ -342,8 +347,9 @@ START_TEST(udev_seat_recycle) udev = udev_new(); ck_assert(udev != NULL); - li = libinput_udev_create_for_seat(&simple_interface, NULL, udev, "seat0"); + li = libinput_udev_create_context(&simple_interface, NULL, udev); ck_assert(li != NULL); + ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0); libinput_dispatch(li); while ((ev = libinput_get_event(li))) { diff --git a/tools/event-debug.c b/tools/event-debug.c index eb43e05..2547da5 100644 --- a/tools/event-debug.c +++ b/tools/event-debug.c @@ -140,12 +140,18 @@ open_udev(struct libinput **li) return 1; } - *li = libinput_udev_create_for_seat(&interface, NULL, udev, seat); + *li = libinput_udev_create_context(&interface, NULL, udev); if (!*li) { fprintf(stderr, "Failed to initialize context from udev\n"); return 1; } + if (libinput_udev_assign_seat(*li, seat)) { + fprintf(stderr, "Failed to set seat\n"); + libinput_destroy(*li); + return 1; + } + return 0; } diff --git a/tools/event-gui.c b/tools/event-gui.c index 9554093..df86a52 100644 --- a/tools/event-gui.c +++ b/tools/event-gui.c @@ -458,8 +458,8 @@ main(int argc, char *argv[]) if (!udev) error("Failed to initialize udev\n"); - li = libinput_udev_create_for_seat(&interface, &w, udev, "seat0"); - if (!li) + li = libinput_udev_create_context(&interface, &w, udev); + if (!li || libinput_udev_assign_seat(li, "seat0") != 0) error("Failed to initialize context from udev\n"); window_init(&w); -- 2.7.4