aboutsummarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntonin Décimo2020-07-08 17:51:12 +0200
committerAntonin Décimo2020-07-08 17:51:12 +0200
commit082514a4689ba64e76d3e53bace46d377a6cb0aa (patch)
tree6c2146743b6afc3658c61279a4065fab760fc131
parentf718ce4278b77896274cc2c68ea625033d338fa5 (diff)
downloadaur-082514a4689ba64e76d3e53bace46d377a6cb0aa.tar.gz
Use custom xwlScaling diff.
-rw-r--r--.SRCINFO6
-rw-r--r--PKGBUILD10
-rw-r--r--xwlScaling.diff636
3 files changed, 644 insertions, 8 deletions
diff --git a/.SRCINFO b/.SRCINFO
index ebcc83525c75..7d24a6004c07 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -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)
diff --git a/PKGBUILD b/PKGBUILD
index 3927eecdbc80..83cf4574d20a 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -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
+ };
+