diff options
author | Antonin Décimo | 2020-07-08 17:51:12 +0200 |
---|---|---|
committer | Antonin Décimo | 2020-07-08 17:51:12 +0200 |
commit | 082514a4689ba64e76d3e53bace46d377a6cb0aa (patch) | |
tree | 6c2146743b6afc3658c61279a4065fab760fc131 | |
parent | f718ce4278b77896274cc2c68ea625033d338fa5 (diff) | |
download | aur-082514a4689ba64e76d3e53bace46d377a6cb0aa.tar.gz |
Use custom xwlScaling diff.
-rw-r--r-- | .SRCINFO | 6 | ||||
-rw-r--r-- | PKGBUILD | 10 | ||||
-rw-r--r-- | xwlScaling.diff | 636 |
3 files changed, 644 insertions, 8 deletions
@@ -1,5 +1,5 @@ pkgbase = xorg-server-hidpi-git - pkgver = 1.20.0.r642.g9890e9126 + pkgver = 1.20.0.r680.g5188603ff pkgrel = 1 url = https://gitlab.freedesktop.org/xorg/xserver.git arch = x86_64 @@ -39,11 +39,11 @@ pkgbase = xorg-server-hidpi-git source = git+https://gitlab.freedesktop.org/xorg/xserver.git source = xvfb-run source = xvfb-run.1 - source = https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/432.diff + source = xwlScaling.diff sha256sums = SKIP sha256sums = ff0156309470fc1d378fd2e104338020a884295e285972cc88e250e031cc35b9 sha256sums = 2460adccd3362fefd4cdc5f1c70f332d7b578091fb9167bf88b5f91265bbd776 - sha256sums = SKIP + sha256sums = 0c9ebc4ffb637a62834f7293c3a0c95e9056dc78d66d5358f6e3af639d1fb978 pkgname = xorg-server-hidpi-git pkgdesc = Xorg X server (git version) @@ -13,8 +13,8 @@ pkgname=( 'xorg-server-common-hidpi-git' 'xorg-server-devel-hidpi-git') _pkgbase='xserver' -pkgver=1.20.0.r642.g9890e9126 -pkgrel=2 +pkgver=1.20.0.r680.g5188603ff +pkgrel=1 arch=('x86_64') license=('custom') groups=('xorg') @@ -28,11 +28,11 @@ makedepends=('xorgproto' 'pixman' 'libx11' 'mesa' 'xtrans' source=(git+https://gitlab.freedesktop.org/xorg/xserver.git xvfb-run xvfb-run.1 - https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/432.diff) + xwlScaling.diff) sha256sums=('SKIP' 'ff0156309470fc1d378fd2e104338020a884295e285972cc88e250e031cc35b9' '2460adccd3362fefd4cdc5f1c70f332d7b578091fb9167bf88b5f91265bbd776' - 'SKIP') + '0c9ebc4ffb637a62834f7293c3a0c95e9056dc78d66d5358f6e3af639d1fb978') pkgver() { cd "${_pkgbase}" @@ -43,7 +43,7 @@ pkgver() { prepare() { cd "${_pkgbase}" - patch -Np1 -i ../432.diff + patch -Np1 -i ../xwlScaling.diff cd .. diff --git a/xwlScaling.diff b/xwlScaling.diff new file mode 100644 index 000000000000..2b265907e32c --- /dev/null +++ b/xwlScaling.diff @@ -0,0 +1,636 @@ +diff --git a/hw/xwayland/Makefile.am b/hw/xwayland/Makefile.am +index cc8a05471..73f19dd6f 100644 +--- a/hw/xwayland/Makefile.am ++++ b/hw/xwayland/Makefile.am +@@ -16,6 +16,8 @@ Xwayland_SOURCES = \ + xwayland-input.h \ + xwayland-cursor.c \ + xwayland-cursor.h \ ++ xwayland-ext.c \ ++ xwayland-ext.h \ + xwayland-glamor.h \ + xwayland-glx.h \ + xwayland-pixmap.c \ +diff --git a/hw/xwayland/meson.build b/hw/xwayland/meson.build +index c41080f20..3ef741c3e 100644 +--- a/hw/xwayland/meson.build ++++ b/hw/xwayland/meson.build +@@ -4,6 +4,8 @@ srcs = [ + 'xwayland-input.h', + 'xwayland-cursor.c', + 'xwayland-cursor.h', ++ 'xwayland-ext.c', ++ 'xwayland-ext.h', + 'xwayland-glamor.h', + 'xwayland-glx.h', + 'xwayland-pixmap.c', +diff --git a/hw/xwayland/xwayland-cursor.c b/hw/xwayland/xwayland-cursor.c +index 91728f1c1..47abac644 100644 +--- a/hw/xwayland/xwayland-cursor.c ++++ b/hw/xwayland/xwayland-cursor.c +@@ -138,6 +138,7 @@ static const struct wl_callback_listener frame_listener = { + void + xwl_seat_set_cursor(struct xwl_seat *xwl_seat) + { ++ struct xwl_screen *xwl_screen = xwl_seat->xwl_screen; + struct xwl_cursor *xwl_cursor = &xwl_seat->cursor; + PixmapPtr pixmap; + CursorPtr cursor; +@@ -174,8 +175,8 @@ xwl_seat_set_cursor(struct xwl_seat *xwl_seat) + wl_pointer_set_cursor(xwl_seat->wl_pointer, + xwl_seat->pointer_enter_serial, + xwl_cursor->surface, +- xwl_seat->x_cursor->bits->xhot, +- xwl_seat->x_cursor->bits->yhot); ++ xwl_scale_to(xwl_screen, xwl_seat->x_cursor->bits->xhot), ++ xwl_scale_to(xwl_screen, xwl_seat->x_cursor->bits->yhot)); + wl_surface_attach(xwl_cursor->surface, + xwl_shm_pixmap_get_wl_buffer(pixmap), 0, 0); + xwl_surface_damage(xwl_seat->xwl_screen, xwl_cursor->surface, 0, 0, +@@ -192,6 +193,7 @@ void + xwl_tablet_tool_set_cursor(struct xwl_tablet_tool *xwl_tablet_tool) + { + struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; ++ struct xwl_screen *xwl_screen = xwl_seat->xwl_screen; + struct xwl_cursor *xwl_cursor = &xwl_tablet_tool->cursor; + PixmapPtr pixmap; + CursorPtr cursor; +@@ -226,8 +228,8 @@ xwl_tablet_tool_set_cursor(struct xwl_tablet_tool *xwl_tablet_tool) + zwp_tablet_tool_v2_set_cursor(xwl_tablet_tool->tool, + xwl_tablet_tool->proximity_in_serial, + xwl_cursor->surface, +- xwl_seat->x_cursor->bits->xhot, +- xwl_seat->x_cursor->bits->yhot); ++ xwl_scale_to(xwl_screen, xwl_seat->x_cursor->bits->xhot), ++ xwl_scale_to(xwl_screen, xwl_seat->x_cursor->bits->yhot)); + wl_surface_attach(xwl_cursor->surface, + xwl_shm_pixmap_get_wl_buffer(pixmap), 0, 0); + xwl_surface_damage(xwl_seat->xwl_screen, xwl_cursor->surface, 0, 0, +diff --git a/hw/xwayland/xwayland-ext.c b/hw/xwayland/xwayland-ext.c +new file mode 100644 +index 000000000..1668dda57 +--- /dev/null ++++ b/hw/xwayland/xwayland-ext.c +@@ -0,0 +1,134 @@ ++/* ++ * Copyright © 2020 Dario Nieuwenhuis ++ * ++ * Permission to use, copy, modify, distribute, and sell this software ++ * and its documentation for any purpose is hereby granted without ++ * fee, provided that the above copyright notice appear in all copies ++ * and that both that copyright notice and this permission notice ++ * appear in supporting documentation, and that the name of the ++ * copyright holders not be used in advertising or publicity ++ * pertaining to distribution of the software without specific, ++ * written prior permission. The copyright holders make no ++ * representations about the suitability of this software for any ++ * purpose. It is provided "as is" without express or implied ++ * warranty. ++ * ++ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS ++ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND ++ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY ++ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN ++ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING ++ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ++ * SOFTWARE. ++ */ ++ ++#ifdef HAVE_DIX_CONFIG_H ++#include <dix-config.h> ++#endif ++ ++#include "dixstruct.h" ++ ++#include <X11/X.h> ++#include "misc.h" ++#include "os.h" ++#include "extinit.h" ++ ++#include "xwayland-ext.h" ++#include "xwayland-screen.h" ++ ++#ifdef DEBUG ++#define DEBUG_P(x) DebugF(x"\n") ++#else ++#define DEBUG_P(x) /**/ ++#endif ++ ++static int XwaylandErrorBase; ++ ++static int ++ProcXwaylandQueryVersion(ClientPtr client) ++{ ++ xXwaylandQueryVersionReply rep = { ++ .type = X_Reply, ++ .sequenceNumber = client->sequence, ++ .length = 0, ++ .majorVersion = XWAYLAND_MAJOR_VERSION, ++ .minorVersion = XWAYLAND_MINOR_VERSION ++ }; ++ ++ DEBUG_P("XwaylandQueryVersion"); ++ ++ REQUEST_SIZE_MATCH(xXwaylandQueryVersionReq); ++ ++ if (client->swapped) { ++ swaps(&rep.sequenceNumber); ++ swapl(&rep.length); ++ swaps(&rep.majorVersion); ++ swaps(&rep.minorVersion); ++ } ++ WriteToClient(client, sizeof(xXwaylandQueryVersionReply), &rep); ++ return Success; ++} ++ ++static int ++ProcXwaylandSetScale(ClientPtr client) ++{ ++ DEBUG_P("XwaylandSetScale"); ++ ++ REQUEST(xXwaylandSetScaleReq); ++ REQUEST_SIZE_MATCH(xXwaylandSetScaleReq); ++ ++ if (stuff->screen >= screenInfo.numScreens) ++ return BadValue; ++ ScreenPtr pScreen = screenInfo.screens[stuff->screen]; ++ ++ struct xwl_screen* xwl_screen = xwl_screen_get(pScreen); ++ if (xwl_screen == NULL) ++ return BadImplementation; ++ ++ if(stuff->scale < 1) ++ return BadValue; ++ ++ xwl_screen_set_global_scale(xwl_screen, stuff->scale); ++ ++ return Success; ++} ++ ++static int ++ProcXwaylandDispatch(ClientPtr client) ++{ ++ REQUEST(xReq); ++ switch (stuff->data) { ++ case X_XwaylandQueryVersion: ++ return ProcXwaylandQueryVersion(client); ++ case X_XwaylandSetScale: ++ return ProcXwaylandSetScale(client); ++ default: ++ return BadRequest; ++ } ++} ++ ++static int _X_COLD ++SProcXwaylandDispatch(ClientPtr client) ++{ ++ REQUEST(xReq); ++ switch (stuff->data) { ++ default: ++ return BadRequest; ++ } ++} ++ ++void ++xwlExtensionInit(void) ++{ ++ ExtensionEntry* extEntry; ++ if ((extEntry = AddExtension(XWAYLANDNAME, ++ XwaylandNumberEvents, ++ XwaylandNumberErrors, ++ ProcXwaylandDispatch, ++ SProcXwaylandDispatch, ++ NULL, StandardMinorOpcode))) { ++ XwaylandErrorBase = extEntry->errorBase; ++ } ++} ++ +diff --git a/hw/xwayland/xwayland-ext.h b/hw/xwayland/xwayland-ext.h +new file mode 100644 +index 000000000..be8fb39d9 +--- /dev/null ++++ b/hw/xwayland/xwayland-ext.h +@@ -0,0 +1,76 @@ ++/* ++ * Copyright © 2020 Dario Nieuwenhuis ++ * ++ * Permission to use, copy, modify, distribute, and sell this software ++ * and its documentation for any purpose is hereby granted without ++ * fee, provided that the above copyright notice appear in all copies ++ * and that both that copyright notice and this permission notice ++ * appear in supporting documentation, and that the name of the ++ * copyright holders not be used in advertising or publicity ++ * pertaining to distribution of the software without specific, ++ * written prior permission. The copyright holders make no ++ * representations about the suitability of this software for any ++ * purpose. It is provided "as is" without express or implied ++ * warranty. ++ * ++ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS ++ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND ++ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY ++ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN ++ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING ++ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ++ * SOFTWARE. ++ */ ++ ++#ifndef XWAYLAND_EXT_H ++#define XWAYLAND_EXT_H ++ ++#include <xwayland-config.h> ++ ++#define XWAYLANDNAME "XWAYLAND" ++#define XwaylandNumberEvents 0 ++#define XwaylandNumberErrors 0 ++ ++#define XWAYLAND_MAJOR_VERSION 1 /* current version numbers */ ++#define XWAYLAND_MINOR_VERSION 0 ++ ++#define X_XwaylandQueryVersion 0 ++#define X_XwaylandSetScale 1 ++ ++ ++typedef struct _XwaylandQueryVersion { ++ CARD8 reqType; /* always XwaylandReqCode */ ++ CARD8 xwaylandReqType; /* always X_XwaylandQueryVersion */ ++ CARD16 length; ++} xXwaylandQueryVersionReq; ++#define sz_xXwaylandQueryVersionReq 4 ++ ++typedef struct { ++ BYTE type; /* X_Reply */ ++ BOOL pad1; ++ CARD16 sequenceNumber; ++ CARD32 length; ++ CARD16 majorVersion; /* major version of Xwayland */ ++ CARD16 minorVersion; /* minor version of Xwayland */ ++ CARD32 pad2; ++ CARD32 pad3; ++ CARD32 pad4; ++ CARD32 pad5; ++ CARD32 pad6; ++} xXwaylandQueryVersionReply; ++#define sz_xXwaylandQueryVersionReply 32 ++ ++ ++typedef struct { ++ CARD8 reqType; /* always XwaylandReqCode */ ++ CARD8 xwaylandReqType; /* always X_XwaylandSetScale */ ++ CARD16 length; ++ CARD16 screen; ++ CARD16 scale; ++} xXwaylandSetScaleReq; ++#define sz_xXwaylandSetScaleReq 8 ++ ++void xwlExtensionInit(void); ++ ++#endif /* XWAYLAND_EXT_H */ +diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c +index d31e0ea4e..f26d84bdc 100644 +--- a/hw/xwayland/xwayland-input.c ++++ b/hw/xwayland/xwayland-input.c +@@ -388,8 +388,8 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer, + DeviceIntPtr dev = xwl_seat->pointer; + DeviceIntPtr master; + int i; +- int sx = wl_fixed_to_int(sx_w); +- int sy = wl_fixed_to_int(sy_w); ++ int sx = wl_fixed_to_int(sx_w) * xwl_seat->xwl_screen->global_output_scale; ++ int sy = wl_fixed_to_int(sy_w) * xwl_seat->xwl_screen->global_output_scale; + int dx, dy; + ScreenPtr pScreen = xwl_seat->xwl_screen->screen; + ValuatorMask mask; +@@ -542,13 +542,14 @@ pointer_handle_motion(void *data, struct wl_pointer *pointer, + uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w) + { + struct xwl_seat *xwl_seat = data; ++ int32_t scale = xwl_seat->xwl_screen->global_output_scale; + + if (!xwl_seat->focus_window) + return; + + xwl_seat->pending_pointer_event.has_absolute = TRUE; +- xwl_seat->pending_pointer_event.x = sx_w; +- xwl_seat->pending_pointer_event.y = sy_w; ++ xwl_seat->pending_pointer_event.x = sx_w * scale; ++ xwl_seat->pending_pointer_event.y = sy_w * scale; + + if (wl_proxy_get_version((struct wl_proxy *) xwl_seat->wl_pointer) < 5) + dispatch_pointer_motion_event(xwl_seat); +@@ -622,7 +623,8 @@ pointer_handle_axis(void *data, struct wl_pointer *pointer, + xorg_list_del(&pending->l); + free(pending); + } else { +- valuator_mask_set_double(&mask, index, wl_fixed_to_double(value) / divisor); ++ double scaled_value = wl_fixed_to_double(value); ++ valuator_mask_set_double(&mask, index, scaled_value / divisor); + } + QueuePointerEvents(xwl_seat->pointer, MotionNotify, 0, POINTER_RELATIVE, &mask); + } +@@ -688,12 +690,13 @@ relative_pointer_handle_relative_motion(void *data, + wl_fixed_t dy_unaccelf) + { + struct xwl_seat *xwl_seat = data; ++ int32_t scale = xwl_seat->xwl_screen->global_output_scale; + + xwl_seat->pending_pointer_event.has_relative = TRUE; +- xwl_seat->pending_pointer_event.dx = wl_fixed_to_double(dxf); +- xwl_seat->pending_pointer_event.dy = wl_fixed_to_double(dyf); +- xwl_seat->pending_pointer_event.dx_unaccel = wl_fixed_to_double(dx_unaccelf); +- xwl_seat->pending_pointer_event.dy_unaccel = wl_fixed_to_double(dy_unaccelf); ++ xwl_seat->pending_pointer_event.dx = wl_fixed_to_double(dxf) * scale; ++ xwl_seat->pending_pointer_event.dy = wl_fixed_to_double(dyf) * scale; ++ xwl_seat->pending_pointer_event.dx_unaccel = wl_fixed_to_double(dx_unaccelf) * scale; ++ xwl_seat->pending_pointer_event.dy_unaccel = wl_fixed_to_double(dy_unaccelf) * scale; + + if (!xwl_seat->focus_window) + return; +@@ -1005,8 +1008,8 @@ touch_handle_down(void *data, struct wl_touch *wl_touch, + + xwl_touch->window = wl_surface_get_user_data(surface); + xwl_touch->id = id; +- xwl_touch->x = wl_fixed_to_int(sx_w); +- xwl_touch->y = wl_fixed_to_int(sy_w); ++ xwl_touch->x = wl_fixed_to_int(sx_w) * xwl_seat->xwl_screen->global_output_scale;; ++ xwl_touch->y = wl_fixed_to_int(sy_w) * xwl_seat->xwl_screen->global_output_scale;; + xorg_list_add(&xwl_touch->link_touch, &xwl_seat->touches); + + xwl_touch_send_event(xwl_touch, xwl_seat, XI_TouchBegin); +@@ -1042,8 +1045,8 @@ touch_handle_motion(void *data, struct wl_touch *wl_touch, + if (!xwl_touch) + return; + +- xwl_touch->x = wl_fixed_to_int(sx_w); +- xwl_touch->y = wl_fixed_to_int(sy_w); ++ xwl_touch->x = wl_fixed_to_int(sx_w) * xwl_seat->xwl_screen->global_output_scale;; ++ xwl_touch->y = wl_fixed_to_int(sy_w) * xwl_seat->xwl_screen->global_output_scale;; + xwl_touch_send_event(xwl_touch, xwl_seat, XI_TouchUpdate); + } + +@@ -1648,8 +1651,8 @@ tablet_tool_motion(void *data, struct zwp_tablet_tool_v2 *tool, + struct xwl_tablet_tool *xwl_tablet_tool = data; + struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; + int32_t dx, dy; +- double sx = wl_fixed_to_double(x); +- double sy = wl_fixed_to_double(y); ++ double sx = wl_fixed_to_double(x) * xwl_seat->xwl_screen->global_output_scale; ++ double sy = wl_fixed_to_double(y) * xwl_seat->xwl_screen->global_output_scale; + + if (!xwl_seat->tablet_focus_window) + return; +@@ -2635,6 +2638,7 @@ xwl_pointer_warp_emulator_set_fake_pos(struct xwl_pointer_warp_emulator *warp_em + int x, + int y) + { ++ struct xwl_screen *xwl_screen; + struct zwp_locked_pointer_v1 *locked_pointer = + warp_emulator->locked_pointer; + WindowPtr window; +@@ -2646,6 +2650,7 @@ xwl_pointer_warp_emulator_set_fake_pos(struct xwl_pointer_warp_emulator *warp_em + if (!warp_emulator->xwl_seat->focus_window) + return; + ++ xwl_screen = warp_emulator->xwl_seat->xwl_screen; + window = warp_emulator->xwl_seat->focus_window->window; + if (x >= window->drawable.x || + y >= window->drawable.y || +@@ -2654,8 +2659,8 @@ xwl_pointer_warp_emulator_set_fake_pos(struct xwl_pointer_warp_emulator *warp_em + sx = x - window->drawable.x; + sy = y - window->drawable.y; + zwp_locked_pointer_v1_set_cursor_position_hint(locked_pointer, +- wl_fixed_from_int(sx), +- wl_fixed_from_int(sy)); ++ wl_fixed_from_int(xwl_scale_to(xwl_screen, sx)), ++ wl_fixed_from_int(xwl_scale_to(xwl_screen, sy))); + wl_surface_commit(warp_emulator->xwl_seat->focus_window->surface); + } + } +diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c +index f94aa0d35..c7bf452e1 100644 +--- a/hw/xwayland/xwayland-output.c ++++ b/hw/xwayland/xwayland-output.c +@@ -186,6 +186,9 @@ update_screen_size(struct xwl_output *xwl_output, int width, int height) + { + struct xwl_screen *xwl_screen = xwl_output->xwl_screen; + ++ width = width * xwl_screen->global_output_scale; ++ height = height * xwl_screen->global_output_scale; ++ + if (xwl_screen->root_clip_mode == ROOT_CLIP_FULL) + SetRootClip(xwl_screen->screen, ROOT_CLIP_NONE); + +@@ -490,8 +493,8 @@ xwl_output_set_emulated_mode(struct xwl_output *xwl_output, ClientPtr client, + xwl_output_set_randr_emu_props(xwl_output->xwl_screen, client); + } + +-static void +-apply_output_change(struct xwl_output *xwl_output) ++void ++xwl_output_apply_changes(struct xwl_output *xwl_output) + { + struct xwl_screen *xwl_screen = xwl_output->xwl_screen; + struct xwl_output *it; +@@ -499,6 +502,7 @@ apply_output_change(struct xwl_output *xwl_output) + int width = 0, height = 0, has_this_output = 0; + RRModePtr *randr_modes; + Bool need_rotate; ++ int32_t scale = xwl_screen->global_output_scale; + + /* Clear out the "done" received flags */ + xwl_output->wl_output_done = FALSE; +@@ -517,10 +521,10 @@ apply_output_change(struct xwl_output *xwl_output) + } + + /* Build a fresh modes array using the current refresh rate */ +- randr_modes = output_get_rr_modes(xwl_output, mode_width, mode_height, &count); ++ randr_modes = output_get_rr_modes(xwl_output, mode_width * scale, mode_height * scale, &count); + RROutputSetModes(xwl_output->randr_output, randr_modes, count, 1); + RRCrtcNotify(xwl_output->randr_crtc, randr_modes[0], +- xwl_output->x, xwl_output->y, ++ xwl_output->x * scale, xwl_output->y * scale, + xwl_output->rotation, NULL, 1, &xwl_output->randr_output); + /* RROutputSetModes takes ownership of the passed in modes, so we only + * have to free the pointer array. +@@ -561,7 +565,7 @@ output_handle_done(void *data, struct wl_output *wl_output) + */ + if (xwl_output->xdg_output_done || !xwl_output->xdg_output || + zxdg_output_v1_get_version(xwl_output->xdg_output) >= 3) +- apply_output_change(xwl_output); ++ xwl_output_apply_changes(xwl_output); + } + + static void +@@ -604,7 +608,7 @@ xdg_output_handle_done(void *data, struct zxdg_output_v1 *xdg_output) + xwl_output->xdg_output_done = TRUE; + if (xwl_output->wl_output_done && + zxdg_output_v1_get_version(xdg_output) < 3) +- apply_output_change(xwl_output); ++ xwl_output_apply_changes(xwl_output); + } + + static void +@@ -671,6 +675,8 @@ xwl_output_create(struct xwl_screen *xwl_screen, uint32_t id) + RROutputSetCrtcs(xwl_output->randr_output, &xwl_output->randr_crtc, 1); + RROutputSetConnection(xwl_output->randr_output, RR_Connected); + ++ xwl_output->scale = 1; ++ + /* We want the output to be in the list as soon as created so we can + * use it when binding to the xdg-output protocol... + */ +diff --git a/hw/xwayland/xwayland-output.h b/hw/xwayland/xwayland-output.h +index 02b983108..ec089757f 100644 +--- a/hw/xwayland/xwayland-output.h ++++ b/hw/xwayland/xwayland-output.h +@@ -43,7 +43,7 @@ struct xwl_output { + struct xwl_screen *xwl_screen; + RROutputPtr randr_output; + RRCrtcPtr randr_crtc; +- int32_t x, y, width, height, refresh; ++ int32_t x, y, width, height, scale, refresh; + Rotation rotation; + Bool wl_output_done; + Bool xdg_output_done; +@@ -77,6 +77,8 @@ void xwl_output_set_emulated_mode(struct xwl_output *xwl_output, + void xwl_output_set_window_randr_emu_props(struct xwl_screen *xwl_screen, + WindowPtr window); + ++void xwl_output_apply_changes(struct xwl_output *xwl_output); ++ + void xwl_screen_init_xdg_output(struct xwl_screen *xwl_screen); + + #endif /* XWAYLAND_OUTPUT_H */ +diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c +index d248a3901..7c889bb9c 100644 +--- a/hw/xwayland/xwayland-screen.c ++++ b/hw/xwayland/xwayland-screen.c +@@ -106,6 +106,12 @@ xwl_screen_has_resolution_change_emulation(struct xwl_screen *xwl_screen) + return xwl_screen->rootless && xwl_screen_has_viewport_support(xwl_screen); + } + ++int ++xwl_scale_to(struct xwl_screen *xwl_screen, int value) ++{ ++ return value / (double)xwl_screen->global_output_scale + 0.5; ++} ++ + /* Return the output @ 0x0, falling back to the first output in the list */ + struct xwl_output * + xwl_screen_get_first_output(struct xwl_screen *xwl_screen) +@@ -519,8 +525,14 @@ void xwl_surface_damage(struct xwl_screen *xwl_screen, + { + if (wl_surface_get_version(surface) >= WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION) + wl_surface_damage_buffer(surface, x, y, width, height); +- else ++ else { ++ x = xwl_scale_to(xwl_screen, x); ++ y = xwl_scale_to(xwl_screen, y); ++ width = xwl_scale_to(xwl_screen, width); ++ height = xwl_scale_to(xwl_screen, height); ++ + wl_surface_damage(surface, x, y, width, height); ++ } + } + + void +@@ -536,6 +548,18 @@ xwl_screen_roundtrip(struct xwl_screen *xwl_screen) + xwl_give_up("could not connect to wayland server\n"); + } + ++void ++xwl_screen_set_global_scale( struct xwl_screen *xwl_screen, int32_t scale) ++{ ++ struct xwl_output *it; ++ xwl_screen->global_output_scale = scale; ++ ++ /* change randr resolutions and positions */ ++ xorg_list_for_each_entry(it, &xwl_screen->output_list, link) { ++ xwl_output_apply_changes(it); ++ } ++} ++ + Bool + xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) + { +@@ -571,6 +595,7 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) + #ifdef XWL_HAS_GLAMOR + xwl_screen->glamor = 1; + #endif ++ xwl_screen->global_output_scale = 1; + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-rootless") == 0) { +diff --git a/hw/xwayland/xwayland-screen.h b/hw/xwayland/xwayland-screen.h +index 8d0b12705..85e0a4fd7 100644 +--- a/hw/xwayland/xwayland-screen.h ++++ b/hw/xwayland/xwayland-screen.h +@@ -72,6 +72,8 @@ struct xwl_screen { + struct xorg_list damage_window_list; + struct xorg_list window_list; + ++ int32_t global_output_scale; ++ + int wayland_fd; + struct wl_display *display; + struct wl_registry *registry; +@@ -130,5 +132,7 @@ void xwl_screen_roundtrip (struct xwl_screen *xwl_screen); + void xwl_surface_damage(struct xwl_screen *xwl_screen, + struct wl_surface *surface, + int32_t x, int32_t y, int32_t width, int32_t height); ++int xwl_scale_to(struct xwl_screen *xwl_screen, int value); ++void xwl_screen_set_global_scale( struct xwl_screen *xwl_screen, int32_t scale); + + #endif /* XWAYLAND_SCREEN_H */ +diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c +index 23d2b3086..f9a7712f4 100644 +--- a/hw/xwayland/xwayland-window.c ++++ b/hw/xwayland/xwayland-window.c +@@ -470,7 +470,8 @@ ensure_surface_for_window(WindowPtr window) + } + + wl_region_add(region, 0, 0, +- window->drawable.width, window->drawable.height); ++ xwl_scale_to(xwl_screen, window->drawable.width), ++ xwl_scale_to(xwl_screen, window->drawable.height)); + wl_surface_set_opaque_region(xwl_window->surface, region); + wl_region_destroy(region); + } +@@ -811,6 +812,7 @@ xwl_window_post_damage(struct xwl_window *xwl_window) + xwl_glamor_post_damage(xwl_window, pixmap, region); + #endif + ++ wl_surface_set_buffer_scale(xwl_window->surface, xwl_screen->global_output_scale); + wl_surface_attach(xwl_window->surface, buffer, 0, 0); + + /* Arbitrary limit to try to avoid flooding the Wayland +diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c +index 380c9c849..c595c4df4 100644 +--- a/hw/xwayland/xwayland.c ++++ b/hw/xwayland/xwayland.c +@@ -41,12 +41,15 @@ + + #include "xwayland-screen.h" + #include "xwayland-vidmode.h" ++#include "xwayland-ext.h" + + #ifdef XF86VIDMODE + #include <X11/extensions/xf86vmproto.h> + extern _X_EXPORT Bool noXFree86VidModeExtension; + #endif + ++_X_EXPORT Bool noXwaylandExtension; ++ + void + ddxGiveUp(enum ExitCode error) + { +@@ -221,6 +224,7 @@ xwl_log_handler(const char *format, va_list args) + static const ExtensionModule xwayland_extensions[] = { + #ifdef XF86VIDMODE + { xwlVidModeExtensionInit, XF86VIDMODENAME, &noXFree86VidModeExtension }, ++ { xwlExtensionInit, XWAYLANDNAME, &noXwaylandExtension }, + #endif + }; + |