wayland: Add support for display connect/disconnect events
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c
index 01444a0..c9d2812 100644
--- a/src/video/wayland/SDL_waylandvideo.c
+++ b/src/video/wayland/SDL_waylandvideo.c
@@ -450,7 +450,7 @@ display_handle_done(void *data,
if (driverdata->index == -1) {
/* First time getting display info, create the VideoDisplay */
driverdata->placeholder.driverdata = driverdata;
- driverdata->index = SDL_AddVideoDisplay(&driverdata->placeholder, SDL_FALSE);
+ driverdata->index = SDL_AddVideoDisplay(&driverdata->placeholder, SDL_TRUE);
SDL_free(driverdata->placeholder.name);
SDL_zero(driverdata->placeholder);
@@ -490,6 +490,7 @@ Wayland_add_display(SDL_VideoData *d, uint32_t id)
data = SDL_malloc(sizeof *data);
SDL_zerop(data);
data->output = output;
+ data->registry_id = id;
data->scale_factor = 1.0;
data->index = -1;
@@ -497,6 +498,35 @@ Wayland_add_display(SDL_VideoData *d, uint32_t id)
SDL_WAYLAND_register_output(output);
}
+static void
+Wayland_free_display(uint32_t id)
+{
+ int num_displays = SDL_GetNumVideoDisplays();
+ SDL_VideoDisplay *display;
+ SDL_WaylandOutputData *data;
+ int i;
+
+ for (i = 0; i < num_displays; i += 1) {
+ display = SDL_GetDisplay(i);
+ data = (SDL_WaylandOutputData *) display->driverdata;
+ if (data->registry_id == id) {
+ SDL_DelVideoDisplay(i);
+ wl_output_destroy(data->output);
+ SDL_free(data);
+
+ /* Update the index for all remaining displays */
+ num_displays -= 1;
+ for (; i < num_displays; i += 1) {
+ display = SDL_GetDisplay(i);
+ data = (SDL_WaylandOutputData *) display->driverdata;
+ data->index -= 1;
+ }
+
+ return;
+ }
+ }
+}
+
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
static void
windowmanager_hints(void *data, struct qt_windowmanager *qt_windowmanager,
@@ -593,7 +623,11 @@ display_handle_global(void *data, struct wl_registry *registry, uint32_t id,
}
static void
-display_remove_global(void *data, struct wl_registry *registry, uint32_t id) {}
+display_remove_global(void *data, struct wl_registry *registry, uint32_t id)
+{
+ /* We don't get an interface, just an ID, so assume it's a wl_output :shrug: */
+ Wayland_free_display(id);
+}
static const struct wl_registry_listener registry_listener = {
display_handle_global,
diff --git a/src/video/wayland/SDL_waylandvideo.h b/src/video/wayland/SDL_waylandvideo.h
index 1568122..4e1d8b2 100644
--- a/src/video/wayland/SDL_waylandvideo.h
+++ b/src/video/wayland/SDL_waylandvideo.h
@@ -90,6 +90,7 @@ typedef struct {
typedef struct {
struct wl_output *output;
+ uint32_t registry_id;
float scale_factor;
int x, y, width, height, refresh, transform;
SDL_DisplayOrientation orientation;