From eb34f827dd9b1a4b641b298060ba11b0d718cff7 Mon Sep 17 00:00:00 2001 From: Marius Vlad Date: Tue, 30 Mar 2021 23:09:05 +0300 Subject: [PATCH] input: Handle correctly failure to compile XKB keymaps And ultimately, fail to start when there are no input devices on the system. Patchs adds consistency to touch/pointer initialization to return -1 in case same thing happens. Further more, when the device is not created we can't assume to retrieve a valid one from a libinput_device so guard against it. This takes care of hot-plugging situations when we couldn't create the (keyboard) device, or when removing it. Fixes: #117, #402, #485 Signed-off-by: Marius Vlad Suggested-by: Daniel Stone --- libweston/input.c | 16 ++++++++++------ libweston/libinput-device.c | 21 +++++++++++++++++++-- libweston/libinput-seat.c | 3 +++ libweston/libweston-internal.h | 4 ++-- 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/libweston/input.c b/libweston/input.c index 8f6abd51..49e30352 100644 --- a/libweston/input.c +++ b/libweston/input.c @@ -3331,7 +3331,7 @@ weston_seat_release_keyboard(struct weston_seat *seat) } } -WL_EXPORT void +WL_EXPORT int weston_seat_init_pointer(struct weston_seat *seat) { struct weston_pointer *pointer; @@ -3340,18 +3340,20 @@ weston_seat_init_pointer(struct weston_seat *seat) seat->pointer_device_count += 1; if (seat->pointer_device_count == 1) seat_send_updated_caps(seat); - return; + return 0; } pointer = weston_pointer_create(seat); if (pointer == NULL) - return; + return -1; seat->pointer_state = pointer; seat->pointer_device_count = 1; pointer->seat = seat; seat_send_updated_caps(seat); + + return 0; } WL_EXPORT void @@ -3377,7 +3379,7 @@ weston_seat_release_pointer(struct weston_seat *seat) } } -WL_EXPORT void +WL_EXPORT int weston_seat_init_touch(struct weston_seat *seat) { struct weston_touch *touch; @@ -3386,18 +3388,20 @@ weston_seat_init_touch(struct weston_seat *seat) seat->touch_device_count += 1; if (seat->touch_device_count == 1) seat_send_updated_caps(seat); - return; + return 0; } touch = weston_touch_create(); if (touch == NULL) - return; + return -1; seat->touch_state = touch; seat->touch_device_count = 1; touch->seat = seat; seat_send_updated_caps(seat); + + return 0; } WL_EXPORT void diff --git a/libweston/libinput-device.c b/libweston/libinput-device.c index 3fd27e91..5cc94284 100644 --- a/libweston/libinput-device.c +++ b/libweston/libinput-device.c @@ -523,6 +523,9 @@ evdev_device_process_event(struct libinput_event *event) int handled = 1; bool need_frame = false; + if (!device) + return 0; + switch (libinput_event_get_type(event)) { case LIBINPUT_EVENT_KEYBOARD_KEY: handle_keyboard_key(libinput_device, @@ -728,13 +731,27 @@ evdev_device_create(struct libinput_device *libinput_device, if (libinput_device_has_capability(libinput_device, LIBINPUT_DEVICE_CAP_KEYBOARD)) { - weston_seat_init_keyboard(seat, NULL); + if (weston_seat_init_keyboard(seat, NULL) < 0) { + free(device); + return NULL; + } + device->seat_caps |= EVDEV_SEAT_KEYBOARD; } if (libinput_device_has_capability(libinput_device, LIBINPUT_DEVICE_CAP_TOUCH)) { - weston_seat_init_touch(seat); + if (weston_seat_init_touch(seat) < 0) { + /* maybe we're a keyboard + touch device thus we need + * to release the keyboard in case we couldn't make use + * of the touch */ + if (device->seat_caps & EVDEV_SEAT_KEYBOARD) + weston_seat_release_keyboard(seat); + + free(device); + return NULL; + } + device->seat_caps |= EVDEV_SEAT_TOUCH; device->touch_device = create_touch_device(device); } diff --git a/libweston/libinput-seat.c b/libweston/libinput-seat.c index 49fbc347..f039ec8b 100644 --- a/libweston/libinput-seat.c +++ b/libweston/libinput-seat.c @@ -150,6 +150,9 @@ device_removed(struct udev_input *input, struct libinput_device *libinput_device struct evdev_device *device; device = libinput_device_get_user_data(libinput_device); + if (!device) + return; + evdev_device_destroy(device); } diff --git a/libweston/libweston-internal.h b/libweston/libweston-internal.h index dad3dad3..81201ee3 100644 --- a/libweston/libweston-internal.h +++ b/libweston/libweston-internal.h @@ -188,13 +188,13 @@ weston_seat_release(struct weston_seat *seat); void weston_seat_send_selection(struct weston_seat *seat, struct wl_client *client); -void +int weston_seat_init_pointer(struct weston_seat *seat); int weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap); -void +int weston_seat_init_touch(struct weston_seat *seat); void