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;
dy = xwl_touch->window->window->drawable.y;
x = (dx + xwl_touch->x) * 0xFFFF / xwl_seat->xwl_screen->width;
y = (dy + xwl_touch->y) * 0xFFFF / xwl_seat->xwl_screen->height;
x = (dx + xwl_touch->x) * 0xFFFF / xwl_screen_get_width(xwl_seat->xwl_screen);
y = (dy + xwl_touch->y) * 0xFFFF / xwl_screen_get_height(xwl_seat->xwl_screen);
valuator_mask_zero(&mask);
valuator_mask_set_double(&mask, 0, x);

View File

@ -25,6 +25,8 @@
#include <xwayland-config.h>
#include <math.h>
#include <X11/Xatom.h>
#include "randrstr_priv.h"
@ -186,8 +188,11 @@ update_backing_pixmaps(struct xwl_screen *xwl_screen, int width, int height)
static void
update_screen_size(struct xwl_screen *xwl_screen, int width, int height)
{
xwl_screen->width = width;
xwl_screen->height = height;
if (xwl_screen_get_width(xwl_screen) != width)
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)
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);
/* If not an emulated mode, just return the actual screen size */
if (!emulated_mode) {
*width = xwl_screen->width;
*height = xwl_screen->height;
*width = xwl_screen_get_width(xwl_screen);
*height = xwl_screen_get_height(xwl_screen);
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);
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 */
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,
NULL, 1, &xwl_output->randr_output);

View File

@ -25,6 +25,7 @@
#include <xwayland-config.h>
#include <math.h>
#include <stdio.h>
#include <unistd.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);
}
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
xwl_property_callback(CallbackListPtr *pcbl, void *closure,
void *calldata)
@ -966,7 +979,8 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
miSetPixmapDepths();
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,
BitsPerPixel(xwl_screen->depth));
if (!ret)

View File

@ -45,8 +45,8 @@
#endif
struct xwl_screen {
int width;
int height;
double width;
double height;
int depth;
int output_name_serial;
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);
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);
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_screen_init(ScreenPtr pScreen, int argc, char **argv);
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;
emulated_mode_ret->server_output_id = 0;
emulated_mode_ret->width = xwl_screen->width;
emulated_mode_ret->height = xwl_screen->height;
emulated_mode_ret->width = xwl_screen_get_width(xwl_screen);
emulated_mode_ret->height = xwl_screen_get_height(xwl_screen);
emulated_mode_ret->from_vidmode = FALSE;
return TRUE;
@ -411,8 +411,8 @@ xwl_window_should_enable_viewport(struct xwl_window *xwl_window,
if (xwl_output && xwl_window->window->overrideRedirect &&
emulated_mode && emulated_mode->from_vidmode &&
drawable->x == 0 && drawable->y == 0 &&
drawable->width == xwl_screen->width &&
drawable->height == xwl_screen->height) {
drawable->width == xwl_screen_get_width(xwl_screen) &&
drawable->height == xwl_screen_get_height(xwl_screen)) {
memcpy(emulated_mode_ret, emulated_mode, sizeof(struct xwl_emulated_mode));
*xwl_output_ret = xwl_output;
@ -637,7 +637,7 @@ xwl_window_rootful_set_app_id(struct xwl_window *xwl_window)
}
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_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)
return;
xwl_screen->width = width;
xwl_screen->height = height;
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;
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_window_attach_buffer(xwl_window);
@ -692,15 +695,17 @@ handle_libdecor_configure(struct libdecor_frame *frame,
struct xwl_window *xwl_window = data;
struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
int width, height;
double new_width, new_height;
if (!libdecor_configuration_get_content_size(configuration, frame, &width, &height)) {
width = xwl_screen->width;
height = xwl_screen->height;
if (libdecor_configuration_get_content_size(configuration, frame, &width, &height)) {
new_width = (double) width;
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_screen->width, xwl_screen->height);
xwl_screen_get_width(xwl_screen),
xwl_screen_get_height(xwl_screen));
wl_surface_commit(xwl_window->surface);
}
@ -1023,7 +1028,12 @@ xwl_realize_window(WindowPtr window)
}
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);
RegionNull(&window->clipList);