From 5cc23868ed335b581c5716e8fb8313495a678ba4 Mon Sep 17 00:00:00 2001 From: Ethan Lee Date: Mon, 15 Nov 2021 11:52:43 -0500 Subject: [PATCH] wayland: Add support for SDL_DisplayOrientation --- src/video/wayland/SDL_waylandvideo.c | 77 ++++++++++++++++++++++++---- src/video/wayland/SDL_waylandvideo.h | 2 + 2 files changed, 70 insertions(+), 9 deletions(-) diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c index 777a1fa01..01444a01b 100644 --- a/src/video/wayland/SDL_waylandvideo.c +++ b/src/video/wayland/SDL_waylandvideo.c @@ -302,12 +302,50 @@ display_handle_geometry(void *data, { SDL_WaylandOutputData *driverdata = data; + if (driverdata->done) { + SDL_ResetDisplayModes(driverdata->index); + + /* The display has officially started over. */ + driverdata->done = SDL_FALSE; + } + driverdata->x = x; driverdata->y = y; driverdata->physical_width = physical_width; driverdata->physical_height = physical_height; - driverdata->placeholder.name = SDL_strdup(model); + if (driverdata->index == -1) { + driverdata->placeholder.name = SDL_strdup(model); + } + driverdata->transform = transform; + #define TF_CASE(in, out) \ + case WL_OUTPUT_TRANSFORM_##in: \ + driverdata->orientation = SDL_ORIENTATION_##out; \ + break; + if (driverdata->physical_width >= driverdata->physical_height) { + switch (transform) { + TF_CASE(NORMAL, LANDSCAPE) + TF_CASE(90, PORTRAIT) + TF_CASE(180, LANDSCAPE_FLIPPED) + TF_CASE(270, PORTRAIT_FLIPPED) + TF_CASE(FLIPPED, LANDSCAPE_FLIPPED) + TF_CASE(FLIPPED_90, PORTRAIT_FLIPPED) + TF_CASE(FLIPPED_180, LANDSCAPE) + TF_CASE(FLIPPED_270, PORTRAIT) + } + } else { + switch (transform) { + TF_CASE(NORMAL, PORTRAIT) + TF_CASE(90, LANDSCAPE) + TF_CASE(180, PORTRAIT_FLIPPED) + TF_CASE(270, LANDSCAPE_FLIPPED) + TF_CASE(FLIPPED, PORTRAIT_FLIPPED) + TF_CASE(FLIPPED_90, LANDSCAPE_FLIPPED) + TF_CASE(FLIPPED_180, PORTRAIT) + TF_CASE(FLIPPED_270, LANDSCAPE) + } + } + #undef TF_CASE } static void @@ -322,6 +360,7 @@ display_handle_mode(void *data, SDL_DisplayMode mode; if (flags & WL_OUTPUT_MODE_CURRENT) { + /* Don't rotate this yet, handle_done will do it later */ driverdata->width = width; driverdata->height = height; driverdata->refresh = refresh; @@ -344,7 +383,11 @@ display_handle_mode(void *data, } mode.refresh_rate = refresh / 1000; /* mHz to Hz */ mode.driverdata = driverdata->output; - SDL_AddDisplayMode(&driverdata->placeholder, &mode); + if (driverdata->index > -1) { + SDL_AddDisplayMode(SDL_GetDisplay(driverdata->index), &mode); + } else { + SDL_AddDisplayMode(&driverdata->placeholder, &mode); + } } static void @@ -353,6 +396,7 @@ display_handle_done(void *data, { SDL_WaylandOutputData* driverdata = data; SDL_DisplayMode mode; + SDL_VideoDisplay *dpy; if (driverdata->done) return; @@ -392,14 +436,28 @@ display_handle_done(void *data, } mode.refresh_rate = driverdata->refresh / 1000; /* mHz to Hz */ mode.driverdata = driverdata->output; - SDL_AddDisplayMode(&driverdata->placeholder, &mode); - driverdata->placeholder.current_mode = mode; - driverdata->placeholder.desktop_mode = mode; - driverdata->placeholder.driverdata = driverdata; - SDL_AddVideoDisplay(&driverdata->placeholder, SDL_FALSE); - SDL_free(driverdata->placeholder.name); - SDL_zero(driverdata->placeholder); + if (driverdata->index > -1) { + dpy = SDL_GetDisplay(driverdata->index); + } else { + dpy = &driverdata->placeholder; + } + + SDL_AddDisplayMode(dpy, &mode); + SDL_SetCurrentDisplayMode(dpy, &mode); + SDL_SetDesktopDisplayMode(dpy, &mode); + + if (driverdata->index == -1) { + /* First time getting display info, create the VideoDisplay */ + driverdata->placeholder.driverdata = driverdata; + driverdata->index = SDL_AddVideoDisplay(&driverdata->placeholder, SDL_FALSE); + SDL_free(driverdata->placeholder.name); + SDL_zero(driverdata->placeholder); + + dpy = SDL_GetDisplay(driverdata->index); + } + + SDL_SendDisplayEvent(dpy, SDL_DISPLAYEVENT_ORIENTATION, driverdata->orientation); } static void @@ -433,6 +491,7 @@ Wayland_add_display(SDL_VideoData *d, uint32_t id) SDL_zerop(data); data->output = output; data->scale_factor = 1.0; + data->index = -1; wl_output_add_listener(output, &output_listener, data); SDL_WAYLAND_register_output(output); diff --git a/src/video/wayland/SDL_waylandvideo.h b/src/video/wayland/SDL_waylandvideo.h index 2d8b6323a..1568122ef 100644 --- a/src/video/wayland/SDL_waylandvideo.h +++ b/src/video/wayland/SDL_waylandvideo.h @@ -92,8 +92,10 @@ typedef struct { struct wl_output *output; float scale_factor; int x, y, width, height, refresh, transform; + SDL_DisplayOrientation orientation; int physical_width, physical_height; float ddpi, hdpi, vdpi; + int index; SDL_VideoDisplay placeholder; SDL_bool done; } SDL_WaylandOutputData;