xwayland: Adjust RandR emulation for rotation

Need to use the extents of the output in screen cordinates, instead of
the canonical mode size.

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2095>
(cherry picked from commit 44dea3a8bd)
This commit is contained in:
Michel Dänzer 2025-11-05 16:31:21 +01:00 committed by Alan Coopersmith
parent 297e29f8c1
commit cdb2cb6cbc
3 changed files with 39 additions and 15 deletions

View file

@ -139,7 +139,7 @@ output_get_logical_mode(struct xwl_output *xwl_output, int *width, int *height)
}
}
static void
void
output_get_logical_extents(struct xwl_output *xwl_output, int *width, int *height)
{
/* When we have xdg-output support the stored size is already rotated. */
@ -518,8 +518,15 @@ xwl_output_randr_emu_prop(struct xwl_screen *xwl_screen, ClientPtr client,
prop->rects[index][0] = xwl_output->logical_x;
prop->rects[index][1] = xwl_output->logical_y;
prop->rects[index][2] = emulated_mode->width;
prop->rects[index][3] = emulated_mode->height;
if (xwl_output->rotation & (RR_Rotate_0 | RR_Rotate_180)) {
prop->rects[index][2] = emulated_mode->width;
prop->rects[index][3] = emulated_mode->height;
} else {
prop->rects[index][2] = emulated_mode->height;
prop->rects[index][3] = emulated_mode->width;
}
index++;
}

View file

@ -111,6 +111,8 @@ void xwl_output_remove(struct xwl_output *xwl_output);
struct xwl_emulated_mode *xwl_output_get_emulated_mode_for_client(
struct xwl_output *xwl_output, ClientPtr client);
void output_get_logical_extents(struct xwl_output *xwl_output, int *width, int *height);
RRModePtr xwl_output_find_mode(struct xwl_output *xwl_output,
int32_t width, int32_t height);
void xwl_output_set_emulated_mode(struct xwl_output *xwl_output,

View file

@ -443,30 +443,35 @@ xwl_window_enable_viewport_for_output(struct xwl_window *xwl_window,
struct xwl_emulated_mode *emulated_mode)
{
struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
int width, height;
int width, height, logical_width, logical_height;
if (xwl_output->rotation & (RR_Rotate_0 | RR_Rotate_180)) {
width = emulated_mode->width / xwl_screen->global_surface_scale;
height = emulated_mode->height / xwl_screen->global_surface_scale;
} else {
width = emulated_mode->height / xwl_screen->global_surface_scale;
height = emulated_mode->width / xwl_screen->global_surface_scale;
}
output_get_logical_extents(xwl_output, &logical_width, &logical_height);
if (!xwl_window_has_viewport_enabled(xwl_window)) {
DebugF("XWAYLAND: enabling viewport %dx%d -> %dx%d\n",
emulated_mode->width, emulated_mode->height,
xwl_output->logical_w, xwl_output->logical_h);
width, height, logical_width, logical_height);
xwl_window->viewport = wp_viewporter_get_viewport(xwl_window->xwl_screen->viewporter,
xwl_window->surface);
}
width = emulated_mode->width / xwl_screen->global_surface_scale;
height = emulated_mode->height / xwl_screen->global_surface_scale;
wp_viewport_set_source(xwl_window->viewport,
wl_fixed_from_int(0),
wl_fixed_from_int(0),
wl_fixed_from_int(width),
wl_fixed_from_int(height));
wp_viewport_set_destination(xwl_window->viewport,
xwl_output->logical_w,
xwl_output->logical_h);
logical_width, logical_height);
xwl_window->viewport_scale_x = (float) width / xwl_output->logical_w;
xwl_window->viewport_scale_y = (float) height / xwl_output->logical_h;
xwl_window->viewport_scale_x = (float) width / logical_width;
xwl_window->viewport_scale_y = (float) height / logical_height;
xwl_window_set_input_region(xwl_window, wInputShape(xwl_window->toplevel));
}
@ -602,14 +607,24 @@ xwl_window_should_enable_viewport(struct xwl_window *xwl_window,
* This path gets hit by most games / libs (e.g. SDL, SFML, OGRE)
*/
xorg_list_for_each_entry(xwl_output, &xwl_screen->output_list, link) {
int emulated_width, emulated_height;
emulated_mode = xwl_output_get_emulated_mode_for_client(xwl_output, owner);
if (!emulated_mode)
continue;
if (xwl_output->rotation & (RR_Rotate_0 | RR_Rotate_180)) {
emulated_width = emulated_mode->width;
emulated_height = emulated_mode->height;
} else {
emulated_width = emulated_mode->height;
emulated_height = emulated_mode->width;
}
if (drawable->x == xwl_output->logical_x &&
drawable->y == xwl_output->logical_y &&
drawable->width == emulated_mode->width &&
drawable->height == emulated_mode->height) {
drawable->width == emulated_width &&
drawable->height == emulated_height) {
memcpy(emulated_mode_ret, emulated_mode, sizeof(struct xwl_emulated_mode));
*xwl_output_ret = xwl_output;