xwayland: Use double for screen size

Use double precision floating point for the screen size to reduce the
rounding issues when using fractional scaling.

Introduce a couple of simple convenient functions that round the
floating point value into an integer and use it in place of directly
accessing the xwl_screen width/height for integer computation.

This is preparation work for the introduction of fractional scaling,
there should be no functional change at this point.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-By: Kenny Levinsen <kl@kl.wtf>
Acked-by: Peter Hutterer <peter.hutterer@who-t.net>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1197>
This commit is contained in:
Olivier Fourdan 2024-02-06 14:51:56 +01:00
parent e1c5be126b
commit 32dad24083
5 changed files with 58 additions and 24 deletions

View File

@ -1387,8 +1387,8 @@ xwl_touch_send_event(struct xwl_touch *xwl_touch,
dx = xwl_touch->window->window->drawable.x; dx = xwl_touch->window->window->drawable.x;
dy = xwl_touch->window->window->drawable.y; dy = xwl_touch->window->window->drawable.y;
x = (dx + xwl_touch->x) * 0xFFFF / xwl_seat->xwl_screen->width; x = (dx + xwl_touch->x) * 0xFFFF / xwl_screen_get_width(xwl_seat->xwl_screen);
y = (dy + xwl_touch->y) * 0xFFFF / xwl_seat->xwl_screen->height; y = (dy + xwl_touch->y) * 0xFFFF / xwl_screen_get_height(xwl_seat->xwl_screen);
valuator_mask_zero(&mask); valuator_mask_zero(&mask);
valuator_mask_set_double(&mask, 0, x); valuator_mask_set_double(&mask, 0, x);

View File

@ -25,6 +25,8 @@
#include <xwayland-config.h> #include <xwayland-config.h>
#include <math.h>
#include <X11/Xatom.h> #include <X11/Xatom.h>
#include "randrstr_priv.h" #include "randrstr_priv.h"
@ -186,8 +188,11 @@ update_backing_pixmaps(struct xwl_screen *xwl_screen, int width, int height)
static void static void
update_screen_size(struct xwl_screen *xwl_screen, int width, int height) update_screen_size(struct xwl_screen *xwl_screen, int width, int height)
{ {
xwl_screen->width = width; if (xwl_screen_get_width(xwl_screen) != width)
xwl_screen->height = height; xwl_screen->width = width;
if (xwl_screen_get_height(xwl_screen) != height)
xwl_screen->height = height;
if (xwl_screen->root_clip_mode == ROOT_CLIP_FULL) if (xwl_screen->root_clip_mode == ROOT_CLIP_FULL)
SetRootClip(xwl_screen->screen, ROOT_CLIP_NONE); SetRootClip(xwl_screen->screen, ROOT_CLIP_NONE);
@ -486,8 +491,8 @@ xwl_output_get_emulated_root_size(struct xwl_output *xwl_output,
emulated_mode = xwl_output_get_emulated_mode_for_client(xwl_output, client); emulated_mode = xwl_output_get_emulated_mode_for_client(xwl_output, client);
/* If not an emulated mode, just return the actual screen size */ /* If not an emulated mode, just return the actual screen size */
if (!emulated_mode) { if (!emulated_mode) {
*width = xwl_screen->width; *width = xwl_screen_get_width(xwl_screen);
*height = xwl_screen->height; *height = xwl_screen_get_height(xwl_screen);
return; return;
} }
@ -1247,10 +1252,12 @@ xwl_screen_init_randr_fixed(struct xwl_screen *xwl_screen)
RROutputSetCrtcs(xwl_output->randr_output, &xwl_output->randr_crtc, 1); RROutputSetCrtcs(xwl_output->randr_output, &xwl_output->randr_crtc, 1);
xwl_randr_add_modes_fixed(xwl_output, xwl_randr_add_modes_fixed(xwl_output,
xwl_screen->width, xwl_screen->height); xwl_screen_get_width(xwl_screen),
xwl_screen_get_height(xwl_screen));
/* Current mode */ /* Current mode */
mode = xwl_output_find_mode(xwl_output, mode = xwl_output_find_mode(xwl_output,
xwl_screen->width, xwl_screen->height); xwl_screen_get_width(xwl_screen),
xwl_screen_get_height(xwl_screen));
RRCrtcNotify(xwl_output->randr_crtc, mode, 0, 0, RR_Rotate_0, RRCrtcNotify(xwl_output->randr_crtc, mode, 0, 0, RR_Rotate_0,
NULL, 1, &xwl_output->randr_output); NULL, 1, &xwl_output->randr_output);

View File

@ -25,6 +25,7 @@
#include <xwayland-config.h> #include <xwayland-config.h>
#include <math.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <errno.h>
@ -145,6 +146,18 @@ xwl_screen_get_fixed_or_first_output(struct xwl_screen *xwl_screen)
return xwl_screen_get_first_output(xwl_screen); return xwl_screen_get_first_output(xwl_screen);
} }
int
xwl_screen_get_width(struct xwl_screen *xwl_screen)
{
return round(xwl_screen->width);
}
int
xwl_screen_get_height(struct xwl_screen *xwl_screen)
{
return round(xwl_screen->height);
}
static void static void
xwl_property_callback(CallbackListPtr *pcbl, void *closure, xwl_property_callback(CallbackListPtr *pcbl, void *closure,
void *calldata) void *calldata)
@ -966,7 +979,8 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
miSetPixmapDepths(); miSetPixmapDepths();
ret = fbScreenInit(pScreen, NULL, ret = fbScreenInit(pScreen, NULL,
xwl_screen->width, xwl_screen->height, xwl_screen_get_width(xwl_screen),
xwl_screen_get_height(xwl_screen),
monitorResolution, monitorResolution, 0, monitorResolution, monitorResolution, 0,
BitsPerPixel(xwl_screen->depth)); BitsPerPixel(xwl_screen->depth));
if (!ret) if (!ret)

View File

@ -45,8 +45,8 @@
#endif #endif
struct xwl_screen { struct xwl_screen {
int width; double width;
int height; double height;
int depth; int depth;
int output_name_serial; int output_name_serial;
ScreenPtr screen; ScreenPtr screen;
@ -157,6 +157,9 @@ Bool xwl_screen_has_resolution_change_emulation(struct xwl_screen *xwl_screen);
void xwl_screen_check_resolution_change_emulation(struct xwl_screen *xwl_screen); void xwl_screen_check_resolution_change_emulation(struct xwl_screen *xwl_screen);
struct xwl_output *xwl_screen_get_first_output(struct xwl_screen *xwl_screen); struct xwl_output *xwl_screen_get_first_output(struct xwl_screen *xwl_screen);
struct xwl_output *xwl_screen_get_fixed_or_first_output(struct xwl_screen *xwl_screen); struct xwl_output *xwl_screen_get_fixed_or_first_output(struct xwl_screen *xwl_screen);
int xwl_screen_get_width(struct xwl_screen *xwl_screen);
int xwl_screen_get_height(struct xwl_screen *xwl_screen);
Bool xwl_close_screen(ScreenPtr screen); Bool xwl_close_screen(ScreenPtr screen);
Bool xwl_screen_init(ScreenPtr pScreen, int argc, char **argv); Bool xwl_screen_init(ScreenPtr pScreen, int argc, char **argv);
void xwl_sync_events (struct xwl_screen *xwl_screen); void xwl_sync_events (struct xwl_screen *xwl_screen);

View File

@ -346,8 +346,8 @@ xwl_window_should_enable_viewport_fullscreen(struct xwl_window *xwl_window,
*xwl_output_ret = xwl_output; *xwl_output_ret = xwl_output;
emulated_mode_ret->server_output_id = 0; emulated_mode_ret->server_output_id = 0;
emulated_mode_ret->width = xwl_screen->width; emulated_mode_ret->width = xwl_screen_get_width(xwl_screen);
emulated_mode_ret->height = xwl_screen->height; emulated_mode_ret->height = xwl_screen_get_height(xwl_screen);
emulated_mode_ret->from_vidmode = FALSE; emulated_mode_ret->from_vidmode = FALSE;
return TRUE; return TRUE;
@ -411,8 +411,8 @@ xwl_window_should_enable_viewport(struct xwl_window *xwl_window,
if (xwl_output && xwl_window->window->overrideRedirect && if (xwl_output && xwl_window->window->overrideRedirect &&
emulated_mode && emulated_mode->from_vidmode && emulated_mode && emulated_mode->from_vidmode &&
drawable->x == 0 && drawable->y == 0 && drawable->x == 0 && drawable->y == 0 &&
drawable->width == xwl_screen->width && drawable->width == xwl_screen_get_width(xwl_screen) &&
drawable->height == xwl_screen->height) { drawable->height == xwl_screen_get_height(xwl_screen)) {
memcpy(emulated_mode_ret, emulated_mode, sizeof(struct xwl_emulated_mode)); memcpy(emulated_mode_ret, emulated_mode, sizeof(struct xwl_emulated_mode));
*xwl_output_ret = xwl_output; *xwl_output_ret = xwl_output;
@ -637,7 +637,7 @@ xwl_window_rootful_set_app_id(struct xwl_window *xwl_window)
} }
static void static void
xwl_window_maybe_resize(struct xwl_window *xwl_window, int width, int height) xwl_window_maybe_resize(struct xwl_window *xwl_window, double width, double height)
{ {
struct xwl_screen *xwl_screen = xwl_window->xwl_screen; struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
struct xwl_output *xwl_output; struct xwl_output *xwl_output;
@ -650,11 +650,14 @@ xwl_window_maybe_resize(struct xwl_window *xwl_window, int width, int height)
if (width == xwl_screen->width && height == xwl_screen->height) if (width == xwl_screen->width && height == xwl_screen->height)
return; return;
xwl_screen->width = width;
xwl_screen->height = height;
xwl_output = xwl_screen_get_fixed_or_first_output(xwl_screen); xwl_output = xwl_screen_get_fixed_or_first_output(xwl_screen);
if (!xwl_randr_add_modes_fixed(xwl_output, width, height)) if (!xwl_randr_add_modes_fixed(xwl_output, round(width), round(height)))
return; return;
mode = xwl_output_find_mode(xwl_output, width, height); mode = xwl_output_find_mode(xwl_output, round(width), round(height));
xwl_output_set_mode_fixed(xwl_output, mode); xwl_output_set_mode_fixed(xwl_output, mode);
xwl_window_attach_buffer(xwl_window); xwl_window_attach_buffer(xwl_window);
@ -692,15 +695,17 @@ handle_libdecor_configure(struct libdecor_frame *frame,
struct xwl_window *xwl_window = data; struct xwl_window *xwl_window = data;
struct xwl_screen *xwl_screen = xwl_window->xwl_screen; struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
int width, height; int width, height;
double new_width, new_height;
if (!libdecor_configuration_get_content_size(configuration, frame, &width, &height)) { if (libdecor_configuration_get_content_size(configuration, frame, &width, &height)) {
width = xwl_screen->width; new_width = (double) width;
height = xwl_screen->height; new_height = (double) height;
} }
xwl_window_maybe_resize(xwl_window, width, height); xwl_window_maybe_resize(xwl_window, new_width, new_height);
xwl_window_update_libdecor_size(xwl_window, configuration, xwl_window_update_libdecor_size(xwl_window, configuration,
xwl_screen->width, xwl_screen->height); xwl_screen_get_width(xwl_screen),
xwl_screen_get_height(xwl_screen));
wl_surface_commit(xwl_window->surface); wl_surface_commit(xwl_window->surface);
} }
@ -1023,7 +1028,12 @@ xwl_realize_window(WindowPtr window)
} }
if (!window->parent) { if (!window->parent) {
BoxRec box = { 0, 0, xwl_screen->width, xwl_screen->height }; BoxRec box = {
0,
0,
xwl_screen_get_width(xwl_screen),
xwl_screen_get_height(xwl_screen)
};
RegionReset(&window->winSize, &box); RegionReset(&window->winSize, &box);
RegionNull(&window->clipList); RegionNull(&window->clipList);