From e862856e6f8c56ec2d3aba5168c9b8b3958561a7 Mon Sep 17 00:00:00 2001 From: Sebastian Krzyszkowiak Date: Mon, 1 Feb 2021 08:57:39 -0800 Subject: [PATCH] wayland: Don't crash when the properties of already existing wl_output change --- src/video/wayland/SDL_waylandvideo.c | 9 ++++++--- src/video/wayland/SDL_waylandvideo.h | 2 ++ src/video/wayland/SDL_waylandwindow.c | 8 ++++++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c index e8315da3b..aec6cc257 100644 --- a/src/video/wayland/SDL_waylandvideo.c +++ b/src/video/wayland/SDL_waylandvideo.c @@ -273,11 +273,15 @@ static void display_handle_done(void *data, struct wl_output *output) { - /* !!! FIXME: this will fail on any further property changes! */ SDL_VideoDisplay *display = data; SDL_WaylandOutputData* driverdata = display->driverdata; SDL_DisplayMode mode; + if (driverdata->done) + return; + + driverdata->done = SDL_TRUE; + SDL_zero(mode); mode.format = SDL_PIXELFORMAT_RGB888; mode.w = driverdata->width / driverdata->scale_factor; @@ -293,9 +297,7 @@ display_handle_done(void *data, display->desktop_mode = mode; SDL_AddVideoDisplay(display, SDL_FALSE); - wl_output_set_user_data(output, display->driverdata); SDL_free(display->name); - SDL_free(display); } static void @@ -335,6 +337,7 @@ Wayland_add_display(SDL_VideoData *d, uint32_t id) data = SDL_malloc(sizeof *data); data->output = output; data->scale_factor = 1.0; + data->done = SDL_FALSE; display->driverdata = data; wl_output_add_listener(output, &output_listener, display); diff --git a/src/video/wayland/SDL_waylandvideo.h b/src/video/wayland/SDL_waylandvideo.h index 04083bff2..354947424 100644 --- a/src/video/wayland/SDL_waylandvideo.h +++ b/src/video/wayland/SDL_waylandvideo.h @@ -20,6 +20,7 @@ */ #include "../../SDL_internal.h" +#include "SDL_stdinc.h" #ifndef SDL_waylandvideo_h_ #define SDL_waylandvideo_h_ @@ -91,6 +92,7 @@ typedef struct { struct wl_output *output; float scale_factor; int width, height, refresh, transform; + SDL_bool done; } SDL_WaylandOutputData; #endif /* SDL_waylandvideo_h_ */ diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c index ab158d22e..fc43735b3 100644 --- a/src/video/wayland/SDL_waylandwindow.c +++ b/src/video/wayland/SDL_waylandwindow.c @@ -414,11 +414,15 @@ update_scale_factor(SDL_WindowData *window) { } if (FULLSCREEN_VISIBLE(window->sdlwindow) && window->sdlwindow->fullscreen_mode.driverdata) { - new_factor = ((SDL_WaylandOutputData*)(wl_output_get_user_data(window->sdlwindow->fullscreen_mode.driverdata)))->scale_factor; + SDL_VideoDisplay *display = wl_output_get_user_data(window->sdlwindow->fullscreen_mode.driverdata); + SDL_WaylandOutputData* driverdata = display->driverdata; + new_factor = driverdata->scale_factor; } for (i = 0; i < window->num_outputs; i++) { - float factor = ((SDL_WaylandOutputData*)(wl_output_get_user_data(window->outputs[i])))->scale_factor; + SDL_VideoDisplay *display = wl_output_get_user_data(window->outputs[i]); + SDL_WaylandOutputData* driverdata = display->driverdata; + float factor = driverdata->scale_factor; if (factor > new_factor) { new_factor = factor; }