From a62848755db42a073be12c09981e24969025550b Mon Sep 17 00:00:00 2001 From: Ningyuan Li Date: Sun, 25 Feb 2024 23:26:19 +0900 Subject: [PATCH] webOS wayland seat fix --- src/video/wayland/SDL_waylandevents.c | 47 +++++++++++++++++++++++++ src/video/wayland/SDL_waylandevents_c.h | 5 +++ 2 files changed, 52 insertions(+) diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c index 93ba9f195a6de..a0e13d5ac5065 100644 --- a/src/video/wayland/SDL_waylandevents.c +++ b/src/video/wayland/SDL_waylandevents.c @@ -2032,6 +2032,13 @@ static void Wayland_create_data_device(SDL_VideoData *d) return; } +#ifdef SDL_VIDEO_DRIVER_WAYLAND_WEBOS + if (d->input->data_device) { + /* Shouldn't be called at all on webOS, but just in case */ + return; + } +#endif + data_device = SDL_calloc(1, sizeof(*data_device)); if (!data_device) { return; @@ -2060,6 +2067,13 @@ static void Wayland_create_primary_selection_device(SDL_VideoData *d) return; } +#ifdef SDL_VIDEO_DRIVER_WAYLAND_WEBOS + if (d->input->primary_selection_device) { + /* Shouldn't be called at all on webOS, but just in case */ + return; + } +#endif + primary_selection_device = SDL_calloc(1, sizeof(*primary_selection_device)); if (!primary_selection_device) { return; @@ -2089,6 +2103,13 @@ static void Wayland_create_text_input(SDL_VideoData *d) return; } +#ifdef SDL_VIDEO_DRIVER_WAYLAND_WEBOS + if (d->input->text_input) { + /* Shouldn't be called at all on webOS, but just in case */ + return; + } +#endif + text_input = SDL_calloc(1, sizeof(*text_input)); if (!text_input) { return; @@ -2467,6 +2488,23 @@ void Wayland_display_add_input(SDL_VideoData *d, uint32_t id, uint32_t version) { struct SDL_WaylandInput *input = d->input; +#ifdef SDL_VIDEO_DRIVER_WAYLAND_WEBOS + if (input->seat) { + struct SDL_WaylandInput *tail; + /* Find the tail if the input has seat */ + while (input->next) { + input = input->next; + } + tail = input; + input = SDL_calloc(1, sizeof(struct SDL_WaylandInput)); + if (!input) { + return; + } + input->display = d; + tail->next = input; + } +#endif + input->seat = wl_registry_bind(d->registry, id, &wl_seat_interface, SDL_min(SDL_WL_SEAT_VERSION, version)); if (d->data_device_manager) { @@ -2573,6 +2611,15 @@ void Wayland_display_destroy_input(SDL_VideoData *d) WAYLAND_xkb_keymap_unref(input->xkb.keymap); } +#ifdef SDL_VIDEO_DRIVER_WAYLAND_WEBOS + /* Use recursive call to free up linked list */ + /* Extremely evil but prevents goto usages and large changes */ + if (input->next) { + d->input = input->next; + Wayland_display_destroy_input(d); + } +#endif + SDL_free(input); d->input = NULL; } diff --git a/src/video/wayland/SDL_waylandevents_c.h b/src/video/wayland/SDL_waylandevents_c.h index 6900645fe0c5a..5d3599b32da63 100644 --- a/src/video/wayland/SDL_waylandevents_c.h +++ b/src/video/wayland/SDL_waylandevents_c.h @@ -147,6 +147,11 @@ struct SDL_WaylandInput SDL_bool relative_mode_override; SDL_bool warp_emulation_prohibited; SDL_bool keyboard_is_virtual; + +#ifdef SDL_VIDEO_DRIVER_WAYLAND_WEBOS + /* On webOS, multiple seats are present. This is a very evil hack to support that non-standard case */ + struct SDL_WaylandInput *next; +#endif }; extern void Wayland_PumpEvents(_THIS);