diff options
author | Antonin Décimo | 2020-12-12 19:38:02 +0100 |
---|---|---|
committer | Antonin Décimo | 2020-12-12 20:47:56 +0100 |
commit | 00132926e8ccf2c8670b0fb6960f38a2d754846b (patch) | |
tree | b960a1fc3c7834a75a6f001c5c50b849ee2fb40a | |
download | aur-00132926e8ccf2c8670b0fb6960f38a2d754846b.tar.gz |
Create xorg-xwayland-hidpi-git from xorg-xwayland 1.20.0.r792.g36e353bcf-5
-rw-r--r-- | .SRCINFO | 46 | ||||
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | PKGBUILD | 83 | ||||
-rw-r--r-- | xwlScaling.diff | 656 |
4 files changed, 786 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO new file mode 100644 index 000000000000..28740fc156cd --- /dev/null +++ b/.SRCINFO @@ -0,0 +1,46 @@ +pkgbase = xorg-xwayland-hidpi-git + pkgdesc = run X clients under wayland + pkgver = 1.20.0.r795.gf95d81e88 + pkgrel = 1 + url = https://xorg.freedesktop.org + arch = x86_64 + groups = xorg + license = custom + makedepends = meson + makedepends = git + makedepends = xorgproto + makedepends = xtrans + makedepends = pixman + makedepends = libxkbfile + makedepends = libxfont2 + makedepends = dbus + makedepends = xorg-font-util + makedepends = wayland + makedepends = wayland-protocols + makedepends = libdrm + makedepends = libepoxy + makedepends = mesa-libgl + makedepends = systemd + makedepends = egl-wayland + depends = nettle + depends = libepoxy + depends = systemd-libs + depends = libxfont2 + depends = pixman + depends = xorg-server-common + provides = xorg-xwayland + provides = xorg-server-xwayland + provides = xorg-server-xwayland-git + provides = xorg-server-xwayland-hidpi-git + conflicts = xorg-xwayland + conflicts = xorg-server-xwayland + conflicts = xorg-server-xwayland-git + conflicts = xorg-server-xwayland-hidpi-git + replaces = xorg-server-xwayland-hidpi-git + source = xserver::git+https://gitlab.freedesktop.org/xorg/xserver.git + source = xwlScaling.diff + sha256sums = SKIP + sha256sums = 139ce463c0f0b3afab23eb42cf00ebcac108856cdc060edc99bbcc329dd991be + +pkgname = xorg-xwayland-hidpi-git + diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000000..72e8ffc0db8a --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +* diff --git a/PKGBUILD b/PKGBUILD new file mode 100644 index 000000000000..cfe6ddc6f971 --- /dev/null +++ b/PKGBUILD @@ -0,0 +1,83 @@ +# Maintainer: Antonin Décimo <antonin dot decimo at gmail dot com> +# Contributor: AndyRTR <andyrtr@archlinux.org> + +pkgname=xorg-xwayland-hidpi-git +pkgver=1.20.0.r795.gf95d81e88 +pkgrel=1 +arch=('x86_64') +license=('custom') +groups=('xorg') +url="https://xorg.freedesktop.org" +pkgdesc="run X clients under wayland" +depends=('nettle' 'libepoxy' 'systemd-libs' 'libxfont2' + 'pixman' 'xorg-server-common') +makedepends=('meson' 'git' + 'xorgproto' 'xtrans' + 'pixman' 'libxkbfile' 'libxfont2' 'dbus' + 'xorg-font-util' + 'wayland' 'wayland-protocols' + 'libdrm' 'libepoxy' 'mesa-libgl' + 'systemd' + 'egl-wayland' +) +source=("xserver::git+https://gitlab.freedesktop.org/xorg/xserver.git" + 'xwlScaling.diff') +sha256sums=('SKIP' + '139ce463c0f0b3afab23eb42cf00ebcac108856cdc060edc99bbcc329dd991be') +provides=('xorg-xwayland' 'xorg-server-xwayland' 'xorg-server-xwayland-git' 'xorg-server-xwayland-hidpi-git') +conflicts=('xorg-xwayland' 'xorg-server-xwayland' 'xorg-server-xwayland-git' 'xorg-server-xwayland-hidpi-git') +replaces=('xorg-server-xwayland-hidpi-git') + +pkgver() { + cd xserver + git describe --tags | sed 's/^xorg.server.//;s/\([^-]*-g\)/r\1/;s/-/./g' +} + +prepare() { + cd xserver + patch --forward --strip=1 --input="${srcdir}/xwlScaling.diff" +} + +build() { + # Since pacman 5.0.2-2, hardened flags are now enabled in makepkg.conf + # With them, module fail to load with undefined symbol. + # See https://bugs.archlinux.org/task/55102 / https://bugs.archlinux.org/task/54845 +# export CFLAGS=${CFLAGS/-fno-plt} +# export CXXFLAGS=${CXXFLAGS/-fno-plt} +# export LDFLAGS=${LDFLAGS/,-z,now} + + arch-meson xserver build \ + -D os_vendor="Arch Linux" \ + -D ipv6=true \ + -D xvfb=false \ + -D xnest=false \ + -D xcsecurity=true \ + -D xorg=false \ + -D xephyr=false \ + -D xwayland=true \ + -D xwayland_eglstream=true \ + -D xwin=false \ + -D xquartz=false \ + -D glamor=true \ + -D udev=true \ + -D systemd_logind=true \ + -D suid_wrapper=true \ + -D xkb_dir=/usr/share/X11/xkb \ + -D xkb_output_dir=/var/lib/xkb + + # Print config + meson configure build + ninja -C build +} + +package() { + + # bin + manpage + .pc file + install -m755 -Dt "${pkgdir}"/usr/bin build/hw/xwayland/Xwayland + install -m644 -Dt "${pkgdir}"/usr/share/man/man1 build/hw/xwayland/Xwayland.1 + install -m644 -Dt "${pkgdir}"/usr/lib/pkgconfig build/hw/xwayland/xwayland.pc + + # license + install -m644 -Dt "${pkgdir}/usr/share/licenses/${pkgname}" xserver/COPYING +} + diff --git a/xwlScaling.diff b/xwlScaling.diff new file mode 100644 index 000000000000..5f3504263a3b --- /dev/null +++ b/xwlScaling.diff @@ -0,0 +1,656 @@ +diff --git a/hw/xwayland/Makefile.am b/hw/xwayland/Makefile.am +index d3dd54364..bcbf98371 100644 +--- a/hw/xwayland/Makefile.am ++++ b/hw/xwayland/Makefile.am +@@ -20,6 +20,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 74895bbec..c5cf38333 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 91cc18464..739e4bf86 100644 +--- a/hw/xwayland/xwayland-cursor.c ++++ b/hw/xwayland/xwayland-cursor.c +@@ -162,6 +162,8 @@ xwl_cursor_attach_pixmap(struct xwl_seat *xwl_seat, + { + wl_surface_attach(xwl_cursor->surface, + xwl_shm_pixmap_get_wl_buffer(pixmap), 0, 0); ++ wl_surface_set_buffer_scale(xwl_cursor->surface, ++ xwl_seat->xwl_screen->global_output_scale); + xwl_surface_damage(xwl_seat->xwl_screen, xwl_cursor->surface, 0, 0, + xwl_seat->x_cursor->bits->width, + xwl_seat->x_cursor->bits->height); +@@ -181,6 +183,7 @@ xwl_cursor_attach_pixmap(struct xwl_seat *xwl_seat, + 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; +@@ -211,8 +214,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)); + + xwl_cursor_attach_pixmap(xwl_seat, xwl_cursor, pixmap); + } +@@ -221,6 +224,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; +@@ -249,8 +253,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)); + + xwl_cursor_attach_pixmap(xwl_seat, xwl_cursor, pixmap); + } +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 12efbe169..c3330d1f6 100644 +--- a/hw/xwayland/xwayland-input.c ++++ b/hw/xwayland/xwayland-input.c +@@ -390,8 +390,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; +@@ -544,13 +544,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); +@@ -624,7 +625,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); + } +@@ -690,12 +692,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; +@@ -1007,8 +1010,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); +@@ -1044,8 +1047,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); + } + +@@ -1650,8 +1653,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; +@@ -2638,6 +2641,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; +@@ -2649,6 +2653,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 || +@@ -2657,8 +2662,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 d4634467d..b27bad110 100644 +--- a/hw/xwayland/xwayland-output.c ++++ b/hw/xwayland/xwayland-output.c +@@ -191,6 +191,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); + +@@ -495,14 +498,15 @@ 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; + int mode_width, mode_height, count; + int width = 0, height = 0, has_this_output = 0; + RRModePtr *randr_modes; ++ int32_t scale = xwl_screen->global_output_scale; + + /* Clear out the "done" received flags */ + xwl_output->wl_output_done = FALSE; +@@ -521,10 +525,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. +@@ -565,7 +569,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 +@@ -608,7 +612,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 +@@ -675,6 +679,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-present.c b/hw/xwayland/xwayland-present.c +index d36b47149..db62982df 100644 +--- a/hw/xwayland/xwayland-present.c ++++ b/hw/xwayland/xwayland-present.c +@@ -467,6 +467,7 @@ xwl_present_flip(WindowPtr present_window, + + /* We can flip directly to the main surface (full screen window without clips) */ + wl_surface_attach(xwl_window->surface, buffer, 0, 0); ++ wl_surface_set_buffer_scale(xwl_window->surface, xwl_window->xwl_screen->global_output_scale); + + if (!xwl_window->frame_callback) + xwl_window_create_frame_callback(xwl_window); +diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c +index c18e2fbb5..3be3674f5 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) +@@ -517,8 +523,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 +@@ -534,6 +546,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) + { +@@ -569,6 +593,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 00a81848a..65e0cb338 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); + } +@@ -812,6 +813,7 @@ xwl_window_post_damage(struct xwl_window *xwl_window) + #endif + + wl_surface_attach(xwl_window->surface, buffer, 0, 0); ++ wl_surface_set_buffer_scale(xwl_window->surface, xwl_screen->global_output_scale); + + /* Arbitrary limit to try to avoid flooding the Wayland + * connection. If we flood it too much anyway, this could +diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c +index 9fc3db976..ad197637e 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) + { +@@ -224,6 +227,7 @@ xwl_log_handler(const char *format, va_list args) + static const ExtensionModule xwayland_extensions[] = { + #ifdef XF86VIDMODE + { xwlVidModeExtensionInit, XF86VIDMODENAME, &noXFree86VidModeExtension }, ++ { xwlExtensionInit, XWAYLANDNAME, &noXwaylandExtension }, + #endif + }; + |