Backport Xwayland randr resolution change emulation support

This commit is contained in:
Hans de Goede 2019-11-04 17:59:36 +01:00
parent 7730e12c9e
commit 3ae2631a52
18 changed files with 2447 additions and 1 deletions

View File

@ -0,0 +1,115 @@
From 7d403201820fb2bdc04bfa8f83c9dd3822c6abda Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 29 Aug 2019 14:18:28 +0200
Subject: [PATCH xserver 01/14] dix: Add GetCurrentClient helper
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Request-handlers as registered in the requestVector array, always get
passed the clientPtr for the client which sent the request.
But the implementation of many request-handlers typically consists of
a generic handler calling implementation specific callbacks and / or
various helpers often multiple levels deep and in many cases the clientPtr
does not get passed to the callbacks / helpers.
This means that in some places where we would like to have access to the
current-client, we cannot easily access it and fixing this would require
a lot of work and often would involve ABI breakage.
This commit adds a GetCurrentClient helper which can be used as a
shortcut to get access to the clienPtr for the currently being processed
request without needing a lot of refactoring and ABI breakage.
Note using this new GetCurrentClient helper is only safe for code
which only runs from the main thread, this new variable MUST NOT be used
by code which runs from signal handlers or from the input-thread.
The specific use-case which resulted in the creation of this patch is adding
support for emulation of randr / vidmode resolution changes to Xwayland.
This emulation will not actually change the monitor resolution instead it
will scale any window with a size which exactly matches the requested
resolution to fill the entire monitor. The main use-case for this is
games which are hard-coded to render at a specific resolution and have
sofar relied on randr / vidmode to change the monitor resolution when going
fullscreen.
To make this emulation as robust as possible (e.g. avoid accidentally scaling
windows from other apps) we want to make the emulated resolution a per client
state. But e.g. the RRSetCrtc function does not take a client pointer; and is
a (used) part of the Xorg server ABI (note the problem is not just limited
to RRSetCrtc).
Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
dix/dispatch.c | 23 ++++++++++++++++++++++-
include/dix.h | 1 +
2 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/dix/dispatch.c b/dix/dispatch.c
index 176c7a0dd..ce84e6c8c 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -148,6 +148,7 @@ xConnSetupPrefix connSetupPrefix;
PaddingInfo PixmapWidthPaddingInfo[33];
static ClientPtr grabClient;
+static ClientPtr currentClient; /* Client for the request currently being dispatched */
#define GrabNone 0
#define GrabActive 1
@@ -176,6 +177,23 @@ volatile char isItTimeToYield;
#define SAME_SCREENS(a, b) (\
(a.pScreen == b.pScreen))
+ClientPtr
+GetCurrentClient(void)
+{
+ if (in_input_thread()) {
+ static Bool warned;
+
+ if (!warned) {
+ ErrorF("[dix] Error GetCurrentClient called from input-thread\n");
+ warned = TRUE;
+ }
+
+ return NULL;
+ }
+
+ return currentClient;
+}
+
void
SetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1)
{
@@ -474,9 +492,12 @@ Dispatch(void)
result = BadLength;
else {
result = XaceHookDispatch(client, client->majorOp);
- if (result == Success)
+ if (result == Success) {
+ currentClient = client;
result =
(*client->requestVector[client->majorOp]) (client);
+ currentClient = NULL;
+ }
}
if (!SmartScheduleSignalEnable)
SmartScheduleTime = GetTimeInMillis();
diff --git a/include/dix.h b/include/dix.h
index b6e2bcfde..d65060cb6 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -148,6 +148,7 @@ typedef struct _TimeStamp {
} TimeStamp;
/* dispatch.c */
+extern _X_EXPORT ClientPtr GetCurrentClient(void);
extern _X_EXPORT void SetInputCheck(HWEventQueuePtr /*c0 */ ,
HWEventQueuePtr /*c1 */ );
--
2.23.0

View File

@ -0,0 +1,118 @@
From f473d009dba1029658f6c3fb5751fbbf027ed468 Mon Sep 17 00:00:00 2001
From: Robert Mader <robert.mader@posteo.de>
Date: Mon, 22 Jan 2018 22:02:32 +0100
Subject: [PATCH xserver 02/14] xwayland: Add wp_viewport wayland extension
support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This commit adds support for the wayland wp_viewport extension, note
nothing uses this yet.
This is a preparation patch for adding support for fake mode-changes through
xrandr for apps which want to change the resolution when going fullscreen.
[hdegoede@redhat.com: Split the code for the extension out into its own patch]
Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
Acked-by: Michel Dänzer <mdaenzer@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/xwayland/Makefile.am | 9 ++++++++-
hw/xwayland/meson.build | 3 +++
hw/xwayland/xwayland.c | 3 +++
hw/xwayland/xwayland.h | 2 ++
5 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/hw/xwayland/Makefile.am b/hw/xwayland/Makefile.am
index bc1cb8506..49aae3d8b 100644
--- a/hw/xwayland/Makefile.am
+++ b/hw/xwayland/Makefile.am
@@ -71,7 +71,9 @@ Xwayland_built_sources += \
xdg-output-unstable-v1-protocol.c \
xdg-output-unstable-v1-client-protocol.h \
linux-dmabuf-unstable-v1-client-protocol.h \
- linux-dmabuf-unstable-v1-protocol.c
+ linux-dmabuf-unstable-v1-protocol.c \
+ viewporter-client-protocol.h \
+ viewporter-protocol.c
if XWAYLAND_EGLSTREAM
Xwayland_built_sources += \
@@ -120,6 +122,11 @@ linux-dmabuf-unstable-v1-protocol.c : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/linu
linux-dmabuf-unstable-v1-client-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@
+viewporter-protocol.c: $(WAYLAND_PROTOCOLS_DATADIR)/stable/viewporter/viewporter.xml
+ $(AM_V_GEN)$(WAYLAND_SCANNER) @SCANNER_ARG@ < $< > $@
+viewporter-client-protocol.h: $(WAYLAND_PROTOCOLS_DATADIR)/stable/viewporter/viewporter.xml
+ $(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@
+
wayland-eglstream-client-protocol.h : $(WAYLAND_EGLSTREAM_DATADIR)/wayland-eglstream.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@
wayland-eglstream-controller-client-protocol.h : $(WAYLAND_EGLSTREAM_DATADIR)/wayland-eglstream-controller.xml
diff --git a/hw/xwayland/meson.build b/hw/xwayland/meson.build
index 36bf2133a..4a8d171bb 100644
--- a/hw/xwayland/meson.build
+++ b/hw/xwayland/meson.build
@@ -21,6 +21,7 @@ tablet_xml = join_paths(protodir, 'unstable', 'tablet', 'tablet-unstable-v2.xml'
kbgrab_xml = join_paths(protodir, 'unstable', 'xwayland-keyboard-grab', 'xwayland-keyboard-grab-unstable-v1.xml')
xdg_output_xml = join_paths(protodir, 'unstable', 'xdg-output', 'xdg-output-unstable-v1.xml')
dmabuf_xml = join_paths(protodir, 'unstable', 'linux-dmabuf', 'linux-dmabuf-unstable-v1.xml')
+viewporter_xml = join_paths(protodir, 'stable', 'viewporter', 'viewporter.xml')
client_header = generator(scanner,
output : '@BASENAME@-client-protocol.h',
@@ -43,12 +44,14 @@ srcs += client_header.process(tablet_xml)
srcs += client_header.process(kbgrab_xml)
srcs += client_header.process(xdg_output_xml)
srcs += client_header.process(dmabuf_xml)
+srcs += client_header.process(viewporter_xml)
srcs += code.process(relative_xml)
srcs += code.process(pointer_xml)
srcs += code.process(tablet_xml)
srcs += code.process(kbgrab_xml)
srcs += code.process(xdg_output_xml)
srcs += code.process(dmabuf_xml)
+srcs += code.process(viewporter_xml)
xwayland_glamor = []
eglstream_srcs = []
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index baa08d87b..292f239e8 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -863,6 +863,9 @@ registry_global(void *data, struct wl_registry *registry, uint32_t id,
wl_registry_bind(registry, id, &zxdg_output_manager_v1_interface, 1);
xwl_screen_init_xdg_output(xwl_screen);
}
+ else if (strcmp(interface, "wp_viewporter") == 0) {
+ xwl_screen->viewporter = wl_registry_bind(registry, id, &wp_viewporter_interface, 1);
+ }
#ifdef XWL_HAS_GLAMOR
else if (xwl_screen->glamor) {
xwl_glamor_init_wl_registry(xwl_screen, registry, id, interface,
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index 0854df456..c4eabe4c3 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -48,6 +48,7 @@
#include "xwayland-keyboard-grab-unstable-v1-client-protocol.h"
#include "xdg-output-unstable-v1-client-protocol.h"
#include "linux-dmabuf-unstable-v1-client-protocol.h"
+#include "viewporter-client-protocol.h"
struct xwl_format {
uint32_t format;
@@ -151,6 +152,7 @@ struct xwl_screen {
struct zwp_pointer_constraints_v1 *pointer_constraints;
struct zwp_xwayland_keyboard_grab_manager_v1 *wp_grab;
struct zxdg_output_manager_v1 *xdg_output_manager;
+ struct wp_viewporter *viewporter;
uint32_t serial;
#define XWL_FORMAT_ARGB8888 (1 << 0)
--
2.23.0

View File

@ -0,0 +1,155 @@
From 0356eff57bc1201e2bcd5fdd363a50ceabc4a4fa Mon Sep 17 00:00:00 2001
From: Robert Mader <robert.mader@posteo.de>
Date: Tue, 2 Jul 2019 12:03:12 +0200
Subject: [PATCH xserver 03/14] xwayland: Use buffer_damage instead of surface
damage if available
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When a viewport is set, damage will only work properly when using
wl_surface_damage_buffer instead of wl_surface_damage.
When no viewport is set, there should be no difference between
surface and buffer damage.
This is a preparation patch for using viewport to add support for fake
mode-changes through xrandr for apps which want to change the resolution
when going fullscreen.
Changes by Hans de Goede <hdegoede@redhat.com>:
-Split the damage changes out into their own patch
-Add xwl_surface_damage helper
-Also use buffer_damage / the new helper for the present and cursor code
Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
Acked-by: Michel Dänzer <mdaenzer@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/xwayland/xwayland-cursor.c | 12 ++++++------
hw/xwayland/xwayland-present.c | 6 +++---
hw/xwayland/xwayland.c | 29 +++++++++++++++++++++++------
hw/xwayland/xwayland.h | 3 +++
4 files changed, 35 insertions(+), 15 deletions(-)
diff --git a/hw/xwayland/xwayland-cursor.c b/hw/xwayland/xwayland-cursor.c
index 66720bcc0..cbc715061 100644
--- a/hw/xwayland/xwayland-cursor.c
+++ b/hw/xwayland/xwayland-cursor.c
@@ -165,9 +165,9 @@ xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
xwl_seat->x_cursor->bits->yhot);
wl_surface_attach(xwl_cursor->surface,
xwl_shm_pixmap_get_wl_buffer(pixmap), 0, 0);
- wl_surface_damage(xwl_cursor->surface, 0, 0,
- xwl_seat->x_cursor->bits->width,
- xwl_seat->x_cursor->bits->height);
+ xwl_surface_damage(xwl_seat->xwl_screen, xwl_cursor->surface, 0, 0,
+ xwl_seat->x_cursor->bits->width,
+ xwl_seat->x_cursor->bits->height);
xwl_cursor->frame_cb = wl_surface_frame(xwl_cursor->surface);
wl_callback_add_listener(xwl_cursor->frame_cb, &frame_listener, xwl_cursor);
@@ -217,9 +217,9 @@ xwl_tablet_tool_set_cursor(struct xwl_tablet_tool *xwl_tablet_tool)
xwl_seat->x_cursor->bits->yhot);
wl_surface_attach(xwl_cursor->surface,
xwl_shm_pixmap_get_wl_buffer(pixmap), 0, 0);
- wl_surface_damage(xwl_cursor->surface, 0, 0,
- xwl_seat->x_cursor->bits->width,
- xwl_seat->x_cursor->bits->height);
+ xwl_surface_damage(xwl_seat->xwl_screen, xwl_cursor->surface, 0, 0,
+ xwl_seat->x_cursor->bits->width,
+ xwl_seat->x_cursor->bits->height);
xwl_cursor->frame_cb = wl_surface_frame(xwl_cursor->surface);
wl_callback_add_listener(xwl_cursor->frame_cb, &frame_listener, xwl_cursor);
diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 2937d9c97..df771c30f 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -500,9 +500,9 @@ xwl_present_flip(WindowPtr present_window,
xwl_present_window->frame_timer_firing = FALSE;
xwl_present_reset_timer(xwl_present_window);
- wl_surface_damage(xwl_window->surface, 0, 0,
- damage_box->x2 - damage_box->x1,
- damage_box->y2 - damage_box->y1);
+ xwl_surface_damage(xwl_window->xwl_screen, xwl_window->surface, 0, 0,
+ damage_box->x2 - damage_box->x1,
+ damage_box->y2 - damage_box->y1);
wl_surface_commit(xwl_window->surface);
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 292f239e8..8b1c7918a 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -759,6 +759,16 @@ xwl_destroy_window(WindowPtr window)
return ret;
}
+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)
+{
+ if (wl_surface_get_version(surface) >= WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION)
+ wl_surface_damage_buffer(surface, x, y, width, height);
+ else
+ wl_surface_damage(surface, x, y, width, height);
+}
+
static void
xwl_window_post_damage(struct xwl_window *xwl_window)
{
@@ -795,13 +805,15 @@ xwl_window_post_damage(struct xwl_window *xwl_window)
*/
if (RegionNumRects(region) > 256) {
box = RegionExtents(region);
- wl_surface_damage(xwl_window->surface, box->x1, box->y1,
- box->x2 - box->x1, box->y2 - box->y1);
+ xwl_surface_damage(xwl_screen, xwl_window->surface, box->x1, box->y1,
+ box->x2 - box->x1, box->y2 - box->y1);
} else {
box = RegionRects(region);
- for (i = 0; i < RegionNumRects(region); i++, box++)
- wl_surface_damage(xwl_window->surface, box->x1, box->y1,
- box->x2 - box->x1, box->y2 - box->y1);
+ for (i = 0; i < RegionNumRects(region); i++, box++) {
+ xwl_surface_damage(xwl_screen, xwl_window->surface,
+ box->x1, box->y1,
+ box->x2 - box->x1, box->y2 - box->y1);
+ }
}
xwl_window->frame_callback = wl_surface_frame(xwl_window->surface);
@@ -844,8 +856,13 @@ registry_global(void *data, struct wl_registry *registry, uint32_t id,
struct xwl_screen *xwl_screen = data;
if (strcmp(interface, "wl_compositor") == 0) {
+ uint32_t request_version = 1;
+
+ if (version >= WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION)
+ request_version = WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION;
+
xwl_screen->compositor =
- wl_registry_bind(registry, id, &wl_compositor_interface, 1);
+ wl_registry_bind(registry, id, &wl_compositor_interface, request_version);
}
else if (strcmp(interface, "wl_shm") == 0) {
xwl_screen->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index c4eabe4c3..3e973d688 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -381,6 +381,9 @@ struct xwl_output {
};
void xwl_sync_events (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);
Bool xwl_screen_init_cursor(struct xwl_screen *xwl_screen);
--
2.23.0

View File

@ -0,0 +1,206 @@
From 873a7d2164c08ddf57e88095b34bbec092f28d31 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Wed, 26 Jun 2019 16:46:54 +0200
Subject: [PATCH xserver 04/14] xwayland: Add fake output modes to xrandr
output mode lists
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This is a preparation patch for adding support for apps which want to
change the resolution when they go fullscreen because they are hardcoded
to render at a specific resolution, e.g. 640x480.
Follow up patches will fake the mode-switch these apps want by using
WPviewport to scale there pixmap to cover the entire output.
Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
Acked-by: Michel Dänzer <mdaenzer@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/xwayland/xwayland-output.c | 112 ++++++++++++++++++++++++++++++++--
hw/xwayland/xwayland.c | 17 ++++++
hw/xwayland/xwayland.h | 1 +
3 files changed, 124 insertions(+), 6 deletions(-)
diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
index aa6f37864..2ccc3ca60 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -245,14 +245,110 @@ update_screen_size(struct xwl_output *xwl_output, int width, int height)
update_desktop_dimensions();
}
+/* From hw/xfree86/common/xf86DefModeSet.c with some obscure modes dropped */
+const int32_t xwl_output_fake_modes[][2] = {
+ /* 4:3 (1.33) */
+ { 2048, 1536 },
+ { 1920, 1440 },
+ { 1600, 1200 },
+ { 1440, 1080 },
+ { 1400, 1050 },
+ { 1280, 1024 }, /* 5:4 (1.25) */
+ { 1280, 960 },
+ { 1152, 864 },
+ { 1024, 768 },
+ { 800, 600 },
+ { 640, 480 },
+ { 320, 240 },
+ /* 16:10 (1.6) */
+ { 2560, 1600 },
+ { 1920, 1200 },
+ { 1680, 1050 },
+ { 1440, 900 },
+ { 1280, 800 },
+ { 720, 480 }, /* 3:2 (1.5) */
+ { 640, 400 },
+ { 320, 200 },
+ /* 16:9 (1.77) */
+ { 5120, 2880 },
+ { 4096, 2304 },
+ { 3840, 2160 },
+ { 3200, 1800 },
+ { 2880, 1620 },
+ { 2560, 1440 },
+ { 2048, 1152 },
+ { 1920, 1080 },
+ { 1600, 900 },
+ { 1368, 768 },
+ { 1280, 720 },
+ { 1024, 576 },
+ { 864, 486 },
+ { 720, 400 },
+ { 640, 350 },
+};
+
+/* Build an array with RRModes the first mode is the actual output mode, the
+ * rest are fake modes from the xwl_output_fake_modes list. We do this for apps
+ * which want to change resolution when they go fullscreen.
+ * When an app requests a mode-change, we fake it using WPviewport.
+ */
+static RRModePtr *
+output_get_rr_modes(struct xwl_output *xwl_output,
+ int32_t width, int32_t height,
+ int *count)
+{
+ struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
+ RRModePtr *rr_modes;
+ int i;
+
+ rr_modes = xallocarray(ARRAY_SIZE(xwl_output_fake_modes) + 1, sizeof(RRModePtr));
+ if (!rr_modes)
+ goto err;
+
+ /* Add actual output mode */
+ rr_modes[0] = xwayland_cvt(width, height, xwl_output->refresh / 1000.0, 0, 0);
+ if (!rr_modes[0])
+ goto err;
+
+ *count = 1;
+
+ if (!xwl_screen_has_resolution_change_emulation(xwl_screen))
+ return rr_modes;
+
+ /* Add fake modes */
+ for (i = 0; i < ARRAY_SIZE(xwl_output_fake_modes); i++) {
+ /* Skip actual output mode, already added */
+ if (xwl_output_fake_modes[i][0] == width &&
+ xwl_output_fake_modes[i][1] == height)
+ continue;
+
+ /* Skip modes which are too big, avoid downscaling */
+ if (xwl_output_fake_modes[i][0] > width ||
+ xwl_output_fake_modes[i][1] > height)
+ continue;
+
+ rr_modes[*count] = xwayland_cvt(xwl_output_fake_modes[i][0],
+ xwl_output_fake_modes[i][1],
+ xwl_output->refresh / 1000.0, 0, 0);
+ if (!rr_modes[*count])
+ goto err;
+
+ (*count)++;
+ }
+
+ return rr_modes;
+err:
+ FatalError("Failed to allocate memory for list of RR modes");
+}
+
static void
apply_output_change(struct xwl_output *xwl_output)
{
struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
struct xwl_output *it;
- int mode_width, mode_height;
+ int mode_width, mode_height, count;
int width = 0, height = 0, has_this_output = 0;
- RRModePtr randr_mode;
+ RRModePtr *randr_modes;
Bool need_rotate;
/* Clear out the "done" received flags */
@@ -271,12 +367,16 @@ apply_output_change(struct xwl_output *xwl_output)
mode_height = xwl_output->width;
}
- randr_mode = xwayland_cvt(mode_width, mode_height,
- xwl_output->refresh / 1000.0, 0, 0);
- RROutputSetModes(xwl_output->randr_output, &randr_mode, 1, 1);
- RRCrtcNotify(xwl_output->randr_crtc, randr_mode,
+ /* Build a fresh modes array using the current refresh rate */
+ randr_modes = output_get_rr_modes(xwl_output, mode_width, mode_height, &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->rotation, NULL, 1, &xwl_output->randr_output);
+ /* RROutputSetModes takes ownership of the passed in modes, so we only
+ * have to free the pointer array.
+ */
+ free(randr_modes);
xorg_list_for_each_entry(it, &xwl_screen->output_list, link) {
/* output done event is sent even when some property
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 8b1c7918a..a599c022a 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -139,6 +139,23 @@ xwl_screen_get(ScreenPtr screen)
return dixLookupPrivate(&screen->devPrivates, &xwl_screen_private_key);
}
+static Bool
+xwl_screen_has_viewport_support(struct xwl_screen *xwl_screen)
+{
+ return wl_compositor_get_version(xwl_screen->compositor) >=
+ WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION &&
+ xwl_screen->viewporter != NULL;
+}
+
+Bool
+xwl_screen_has_resolution_change_emulation(struct xwl_screen *xwl_screen)
+{
+ /* Resolution change emulation is only supported in rootless mode and
+ * it requires viewport support.
+ */
+ return xwl_screen->rootless && xwl_screen_has_viewport_support(xwl_screen);
+}
+
static void
xwl_window_set_allow_commits(struct xwl_window *xwl_window, Bool allow,
const char *debug_msg)
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index 3e973d688..0fafc07a6 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -388,6 +388,7 @@ void xwl_surface_damage(struct xwl_screen *xwl_screen,
Bool xwl_screen_init_cursor(struct xwl_screen *xwl_screen);
struct xwl_screen *xwl_screen_get(ScreenPtr screen);
+Bool xwl_screen_has_resolution_change_emulation(struct xwl_screen *xwl_screen);
void xwl_tablet_tool_set_cursor(struct xwl_tablet_tool *tool);
void xwl_seat_set_cursor(struct xwl_seat *xwl_seat);
--
2.23.0

View File

@ -0,0 +1,138 @@
From 81ff61afd6594e0cf00f4be7ff34f94cd9e8f9b0 Mon Sep 17 00:00:00 2001
From: Robert Mader <robert.mader@posteo.de>
Date: Mon, 22 Jan 2018 17:57:38 +0100
Subject: [PATCH xserver 05/14] xwayland: Use RandR 1.2 interface (rev 2)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This adds the RandR 1.2 interface to xwayland and allows modes
advertised by the compositor to be set in an undistructive manner.
With this patch, applications that try to set the resolution will usually
succeed and work while other apps using the same xwayland
instance are not affected at all.
The RandR 1.2 interface will be needed to implement fake-mode-setting and
already makes applications work much cleaner and predictive when a mode
was set.
[hdegoede@redhat.com: Make crtc_set only succeed if the mode matches
the desktop resolution]
Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
Acked-by: Michel Dänzer <mdaenzer@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/xwayland/xwayland-output.c | 81 +++++++++++++++++++++++++++++++++++
1 file changed, 81 insertions(+)
diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
index 2ccc3ca60..67e99bdab 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -561,12 +561,80 @@ xwl_randr_get_info(ScreenPtr pScreen, Rotation * rotations)
return TRUE;
}
+#ifdef RANDR_10_INTERFACE
static Bool
xwl_randr_set_config(ScreenPtr pScreen,
Rotation rotation, int rate, RRScreenSizePtr pSize)
{
return FALSE;
}
+#endif
+
+#if RANDR_12_INTERFACE
+static Bool
+xwl_randr_screen_set_size(ScreenPtr pScreen,
+ CARD16 width,
+ CARD16 height,
+ CARD32 mmWidth, CARD32 mmHeight)
+{
+ return TRUE;
+}
+
+static Bool
+xwl_randr_crtc_set(ScreenPtr pScreen,
+ RRCrtcPtr crtc,
+ RRModePtr mode,
+ int x,
+ int y,
+ Rotation rotation,
+ int numOutputs, RROutputPtr * outputs)
+{
+ struct xwl_output *xwl_output = crtc->devPrivate;
+
+ if (!mode || (mode->mode.width == xwl_output->width &&
+ mode->mode.height == xwl_output->height)) {
+ RRCrtcChanged(crtc, TRUE);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static Bool
+xwl_randr_crtc_set_gamma(ScreenPtr pScreen, RRCrtcPtr crtc)
+{
+ return TRUE;
+}
+
+static Bool
+xwl_randr_crtc_get_gamma(ScreenPtr pScreen, RRCrtcPtr crtc)
+{
+ return TRUE;
+}
+
+static Bool
+xwl_randr_output_set_property(ScreenPtr pScreen,
+ RROutputPtr output,
+ Atom property,
+ RRPropertyValuePtr value)
+{
+ return TRUE;
+}
+
+static Bool
+xwl_output_validate_mode(ScreenPtr pScreen,
+ RROutputPtr output,
+ RRModePtr mode)
+{
+ return TRUE;
+}
+
+static void
+xwl_randr_mode_destroy(ScreenPtr pScreen, RRModePtr mode)
+{
+ return;
+}
+#endif
Bool
xwl_screen_init_output(struct xwl_screen *xwl_screen)
@@ -580,7 +648,20 @@ xwl_screen_init_output(struct xwl_screen *xwl_screen)
rp = rrGetScrPriv(xwl_screen->screen);
rp->rrGetInfo = xwl_randr_get_info;
+
+#if RANDR_10_INTERFACE
rp->rrSetConfig = xwl_randr_set_config;
+#endif
+
+#if RANDR_12_INTERFACE
+ rp->rrScreenSetSize = xwl_randr_screen_set_size;
+ rp->rrCrtcSet = xwl_randr_crtc_set;
+ rp->rrCrtcSetGamma = xwl_randr_crtc_set_gamma;
+ rp->rrCrtcGetGamma = xwl_randr_crtc_get_gamma;
+ rp->rrOutputSetProperty = xwl_randr_output_set_property;
+ rp->rrOutputValidateMode = xwl_output_validate_mode;
+ rp->rrModeDestroy = xwl_randr_mode_destroy;
+#endif
return TRUE;
}
--
2.23.0

View File

@ -0,0 +1,77 @@
From 1dc4938467b6338695eda4224f0b0c592cb2c25c Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 29 Aug 2019 22:45:12 +0200
Subject: [PATCH xserver 06/14] xwayland: Add per client private data
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add per client private data, which for now is empty.
This is a preparation patch for adding randr/vidmode resolution
change emulation.
Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
Acked-by: Michel Dänzer <mdaenzer@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/xwayland/xwayland.c | 14 ++++++++++++++
hw/xwayland/xwayland.h | 5 +++++
2 files changed, 19 insertions(+)
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index a599c022a..2b6065f1a 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -122,11 +122,18 @@ ddxProcessArgument(int argc, char *argv[], int i)
return 0;
}
+static DevPrivateKeyRec xwl_client_private_key;
static DevPrivateKeyRec xwl_window_private_key;
static DevPrivateKeyRec xwl_screen_private_key;
static DevPrivateKeyRec xwl_pixmap_private_key;
static DevPrivateKeyRec xwl_damage_private_key;
+struct xwl_client *
+xwl_client_get(ClientPtr client)
+{
+ return dixLookupPrivate(&client->devPrivates, &xwl_client_private_key);
+}
+
static struct xwl_window *
xwl_window_get(WindowPtr window)
{
@@ -1083,6 +1090,13 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
return FALSE;
if (!dixRegisterPrivateKey(&xwl_damage_private_key, PRIVATE_WINDOW, 0))
return FALSE;
+ /* There are no easy to use new / delete client hooks, we could use a
+ * ClientStateCallback, but it is easier to let the dix code manage the
+ * memory for us. This will zero fill the initial xwl_client data.
+ */
+ if (!dixRegisterPrivateKey(&xwl_client_private_key, PRIVATE_CLIENT,
+ sizeof(struct xwl_client)))
+ return FALSE;
dixSetPrivate(&pScreen->devPrivates, &xwl_screen_private_key, xwl_screen);
xwl_screen->screen = pScreen;
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index 0fafc07a6..17018fcf5 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -380,6 +380,11 @@ struct xwl_output {
Bool xdg_output_done;
};
+struct xwl_client {
+};
+
+struct xwl_client *xwl_client_get(ClientPtr client);
+
void xwl_sync_events (struct xwl_screen *xwl_screen);
void xwl_surface_damage(struct xwl_screen *xwl_screen,
struct wl_surface *surface,
--
2.23.0

View File

@ -0,0 +1,148 @@
From dfb887783bfe3c5f57d46738bce13ec2d79b1769 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 29 Aug 2019 23:04:36 +0200
Subject: [PATCH xserver 07/14] xwayland: Add support for storing per client
per output emulated resolution
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add support for storing per output randr/vidmode emulated resolution
into the per client data.
Since we do not have a free/delete callback for the client this uses
a simple static array. The entries are tied to a specific output by the
server_output_id, with a server_output_id of 0 indicating a free slot
(0 is the "None" Wayland object id).
Note that even if we were to store this in a linked list, we would still
need the server_output_id as this is *per client* *per output*.
This is a preparation patch for adding randr/vidmode resolution
change emulation.
Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
Acked-by: Michel Dänzer <mdaenzer@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/xwayland/xwayland-output.c | 67 +++++++++++++++++++++++++++++++++++
hw/xwayland/xwayland.h | 17 +++++++++
2 files changed, 84 insertions(+)
diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
index 67e99bdab..82ff5db70 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -245,6 +245,73 @@ update_screen_size(struct xwl_output *xwl_output, int width, int height)
update_desktop_dimensions();
}
+struct xwl_emulated_mode *
+xwl_output_get_emulated_mode_for_client(struct xwl_output *xwl_output,
+ ClientPtr client)
+{
+ struct xwl_client *xwl_client = xwl_client_get(client);
+ int i;
+
+ if (!xwl_output)
+ return NULL;
+
+ for (i = 0; i < XWL_CLIENT_MAX_EMULATED_MODES; i++) {
+ if (xwl_client->emulated_modes[i].server_output_id ==
+ xwl_output->server_output_id)
+ return &xwl_client->emulated_modes[i];
+ }
+
+ return NULL;
+}
+
+static void
+xwl_output_add_emulated_mode_for_client(struct xwl_output *xwl_output,
+ ClientPtr client,
+ RRModePtr mode,
+ Bool from_vidmode)
+{
+ struct xwl_client *xwl_client = xwl_client_get(client);
+ struct xwl_emulated_mode *emulated_mode;
+ int i;
+
+ emulated_mode = xwl_output_get_emulated_mode_for_client(xwl_output, client);
+ if (!emulated_mode) {
+ /* Find a free spot in the emulated modes array */
+ for (i = 0; i < XWL_CLIENT_MAX_EMULATED_MODES; i++) {
+ if (xwl_client->emulated_modes[i].server_output_id == 0) {
+ emulated_mode = &xwl_client->emulated_modes[i];
+ break;
+ }
+ }
+ }
+ if (!emulated_mode) {
+ static Bool warned;
+
+ if (!warned) {
+ ErrorF("Ran out of space for emulated-modes, not adding mode");
+ warned = TRUE;
+ }
+
+ return;
+ }
+
+ emulated_mode->server_output_id = xwl_output->server_output_id;
+ emulated_mode->width = mode->mode.width;
+ emulated_mode->height = mode->mode.height;
+ emulated_mode->from_vidmode = from_vidmode;
+}
+
+static void
+xwl_output_remove_emulated_mode_for_client(struct xwl_output *xwl_output,
+ ClientPtr client)
+{
+ struct xwl_emulated_mode *emulated_mode;
+
+ emulated_mode = xwl_output_get_emulated_mode_for_client(xwl_output, client);
+ if (emulated_mode)
+ memset(emulated_mode, 0, sizeof(*emulated_mode));
+}
+
/* From hw/xfree86/common/xf86DefModeSet.c with some obscure modes dropped */
const int32_t xwl_output_fake_modes[][2] = {
/* 4:3 (1.33) */
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index 17018fcf5..d0e87a89d 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -380,7 +380,21 @@ struct xwl_output {
Bool xdg_output_done;
};
+/* Per client per output emulated randr/vidmode resolution info. */
+struct xwl_emulated_mode {
+ uint32_t server_output_id;
+ int32_t width;
+ int32_t height;
+ Bool from_vidmode;
+};
+
+/* Apps which use randr/vidmode to change the mode when going fullscreen,
+ * usually change the mode of only a single monitor, so this should be plenty.
+ */
+#define XWL_CLIENT_MAX_EMULATED_MODES 16
+
struct xwl_client {
+ struct xwl_emulated_mode emulated_modes[XWL_CLIENT_MAX_EMULATED_MODES];
};
struct xwl_client *xwl_client_get(ClientPtr client);
@@ -424,6 +438,9 @@ void xwl_output_destroy(struct xwl_output *xwl_output);
void xwl_output_remove(struct xwl_output *xwl_output);
+struct xwl_emulated_mode *xwl_output_get_emulated_mode_for_client(
+ struct xwl_output *xwl_output, ClientPtr client);
+
RRModePtr xwayland_cvt(int HDisplay, int VDisplay,
float VRefresh, Bool Reduced, Bool Interlaced);
--
2.23.0

View File

@ -0,0 +1,461 @@
From e997273b14a23b0ffe89f542de783adbec6e8a1b Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Tue, 2 Jul 2019 11:55:26 +0200
Subject: [PATCH xserver 08/14] xwayland: Add support for randr-resolution
change emulation using viewport
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add support for per client randr-resolution change emulation using viewport,
for apps which want to change the resolution when going fullscreen.
Partly based on earlier work on this by Robert Mader <robert.mader@posteo.de>
Note SDL2 and SFML do not restore randr resolution when going from
fullscreen -> windowed, I believe this is caused by us still reporting the
desktop resolution when they query the resolution. This is not a problem
because when windowed the toplevel window size includes the window-decorations
so it never matches the emulated resolution.
One exception would be the window being resizable in Windowed mode and the
user resizing the window so that including decorations it matches the
emulated resolution *and* the window being at pos 0x0. But this is an
extreme corner case. Still I will submit patches upstream to SDL2
and SFML to always restore the desktop resolution under Xwayland,
disabling resolution emulation all together when going windowed.
Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
Acked-by: Michel Dänzer <mdaenzer@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/xwayland/xwayland-input.c | 5 +
hw/xwayland/xwayland-output.c | 63 ++++++++++-
hw/xwayland/xwayland.c | 199 ++++++++++++++++++++++++++++++++++
hw/xwayland/xwayland.h | 15 +++
4 files changed, 276 insertions(+), 6 deletions(-)
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index fa46ac3e7..97b8cd132 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -486,6 +486,11 @@ dispatch_pointer_motion_event(struct xwl_seat *xwl_seat)
int dx = xwl_seat->focus_window->window->drawable.x;
int dy = xwl_seat->focus_window->window->drawable.y;
+ if (xwl_window_has_viewport_enabled(xwl_seat->focus_window)) {
+ sx *= xwl_seat->focus_window->scale_x;
+ sy *= xwl_seat->focus_window->scale_y;
+ }
+
x = dx + sx;
y = dy + sy;
} else {
diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
index 82ff5db70..99ab1b288 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -408,6 +408,42 @@ err:
FatalError("Failed to allocate memory for list of RR modes");
}
+RRModePtr
+xwl_output_find_mode(struct xwl_output *xwl_output,
+ int32_t width, int32_t height)
+{
+ RROutputPtr output = xwl_output->randr_output;
+ int i;
+
+ /* width & height -1 means we want the actual output mode, which is idx 0 */
+ if (width == -1 && height == -1 && output->modes)
+ return output->modes[0];
+
+ for (i = 0; i < output->numModes; i++) {
+ if (output->modes[i]->mode.width == width && output->modes[i]->mode.height == height)
+ return output->modes[i];
+ }
+
+ ErrorF("XWAYLAND: mode %dx%d is not available\n", width, height);
+ return NULL;
+}
+
+void
+xwl_output_set_emulated_mode(struct xwl_output *xwl_output, ClientPtr client,
+ RRModePtr mode, Bool from_vidmode)
+{
+ DebugF("XWAYLAND: xwl_output_set_emulated_mode from %s: %dx%d\n",
+ from_vidmode ? "vidmode" : "randr",
+ mode->mode.width, mode->mode.height);
+
+ if (mode->mode.width == xwl_output->width && mode->mode.height == xwl_output->height)
+ xwl_output_remove_emulated_mode_for_client(xwl_output, client);
+ else
+ xwl_output_add_emulated_mode_for_client(xwl_output, client, mode, from_vidmode);
+
+ xwl_screen_check_resolution_change_emulation(xwl_output->xwl_screen);
+}
+
static void
apply_output_change(struct xwl_output *xwl_output)
{
@@ -650,21 +686,36 @@ xwl_randr_screen_set_size(ScreenPtr pScreen,
static Bool
xwl_randr_crtc_set(ScreenPtr pScreen,
RRCrtcPtr crtc,
- RRModePtr mode,
+ RRModePtr new_mode,
int x,
int y,
Rotation rotation,
int numOutputs, RROutputPtr * outputs)
{
struct xwl_output *xwl_output = crtc->devPrivate;
+ RRModePtr mode;
- if (!mode || (mode->mode.width == xwl_output->width &&
- mode->mode.height == xwl_output->height)) {
- RRCrtcChanged(crtc, TRUE);
- return TRUE;
+ if (new_mode) {
+ mode = xwl_output_find_mode(xwl_output,
+ new_mode->mode.width,
+ new_mode->mode.height);
+ } else {
+ mode = xwl_output_find_mode(xwl_output, -1, -1);
}
+ if (!mode)
+ return FALSE;
- return FALSE;
+ xwl_output_set_emulated_mode(xwl_output, GetCurrentClient(), mode, FALSE);
+
+ /* A real randr implementation would call:
+ * RRCrtcNotify(xwl_output->randr_crtc, mode, xwl_output->x, xwl_output->y,
+ * xwl_output->rotation, NULL, 1, &xwl_output->randr_output);
+ * here to update the mode reported to clients querying the randr settings
+ * but that influences *all* clients and we do randr mode change emulation
+ * on a per client basis. So we just return success here.
+ */
+
+ return TRUE;
}
static Bool
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 2b6065f1a..ec1b7eee4 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -163,6 +163,23 @@ xwl_screen_has_resolution_change_emulation(struct xwl_screen *xwl_screen)
return xwl_screen->rootless && xwl_screen_has_viewport_support(xwl_screen);
}
+/* 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)
+{
+ struct xwl_output *xwl_output;
+
+ xorg_list_for_each_entry(xwl_output, &xwl_screen->output_list, link) {
+ if (xwl_output->x == 0 && xwl_output->y == 0)
+ return xwl_output;
+ }
+
+ if (xorg_list_is_empty(&xwl_screen->output_list))
+ return NULL;
+
+ return xorg_list_first_entry(&xwl_screen->output_list, struct xwl_output, link);
+}
+
static void
xwl_window_set_allow_commits(struct xwl_window *xwl_window, Bool allow,
const char *debug_msg)
@@ -499,6 +516,150 @@ xwl_pixmap_get(PixmapPtr pixmap)
return dixLookupPrivate(&pixmap->devPrivates, &xwl_pixmap_private_key);
}
+Bool
+xwl_window_has_viewport_enabled(struct xwl_window *xwl_window)
+{
+ return (xwl_window->viewport != NULL);
+}
+
+static void
+xwl_window_disable_viewport(struct xwl_window *xwl_window)
+{
+ assert (xwl_window->viewport);
+
+ DebugF("XWAYLAND: disabling viewport\n");
+ wp_viewport_destroy(xwl_window->viewport);
+ xwl_window->viewport = NULL;
+}
+
+static void
+xwl_window_enable_viewport(struct xwl_window *xwl_window,
+ struct xwl_output *xwl_output,
+ struct xwl_emulated_mode *emulated_mode)
+{
+ /* If necessary disable old viewport to apply new settings */
+ if (xwl_window_has_viewport_enabled(xwl_window))
+ xwl_window_disable_viewport(xwl_window);
+
+ DebugF("XWAYLAND: enabling viewport %dx%d -> %dx%d\n",
+ emulated_mode->width, emulated_mode->height,
+ xwl_output->width, xwl_output->height);
+
+ xwl_window->viewport =
+ wp_viewporter_get_viewport(xwl_window->xwl_screen->viewporter,
+ xwl_window->surface);
+
+ wp_viewport_set_source(xwl_window->viewport,
+ wl_fixed_from_int(0),
+ wl_fixed_from_int(0),
+ wl_fixed_from_int(emulated_mode->width),
+ wl_fixed_from_int(emulated_mode->height));
+ wp_viewport_set_destination(xwl_window->viewport,
+ xwl_output->width,
+ xwl_output->height);
+
+ xwl_window->scale_x = (float)emulated_mode->width / xwl_output->width;
+ xwl_window->scale_y = (float)emulated_mode->height / xwl_output->height;
+}
+
+static Bool
+xwl_screen_client_is_window_manager(struct xwl_screen *xwl_screen,
+ ClientPtr client)
+{
+ WindowPtr root = xwl_screen->screen->root;
+ OtherClients *others;
+
+ for (others = wOtherClients(root); others; others = others->next) {
+ if (SameClient(others, client)) {
+ if (others->mask & (SubstructureRedirectMask | ResizeRedirectMask))
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static ClientPtr
+xwl_window_get_owner(struct xwl_window *xwl_window)
+{
+ WindowPtr window = xwl_window->window;
+ ClientPtr client = wClient(window);
+
+ /* If the toplevel window is owned by the window-manager, then the
+ * actual client toplevel window has been reparented to a window-manager
+ * decoration window. In that case return the client of the
+ * first *and only* child of the toplevel (decoration) window.
+ */
+ if (xwl_screen_client_is_window_manager(xwl_window->xwl_screen, client)) {
+ if (window->firstChild && window->firstChild == window->lastChild)
+ return wClient(window->firstChild);
+ else
+ return NULL; /* Should never happen, skip resolution emulation */
+ }
+
+ return client;
+}
+
+static Bool
+xwl_window_should_enable_viewport(struct xwl_window *xwl_window,
+ struct xwl_output **xwl_output_ret,
+ struct xwl_emulated_mode **emulated_mode_ret)
+{
+ struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
+ struct xwl_emulated_mode *emulated_mode;
+ struct xwl_output *xwl_output;
+ ClientPtr owner;
+
+ if (!xwl_screen_has_resolution_change_emulation(xwl_screen))
+ return FALSE;
+
+ owner = xwl_window_get_owner(xwl_window);
+ if (!owner)
+ return FALSE;
+
+ /* 1. Test if the window matches the emulated mode on one of the outputs
+ * This path gets hit by most games / libs (e.g. SDL, SFML, OGRE)
+ */
+ xorg_list_for_each_entry(xwl_output, &xwl_screen->output_list, link) {
+ emulated_mode = xwl_output_get_emulated_mode_for_client(xwl_output, owner);
+ if (!emulated_mode)
+ continue;
+
+ if (xwl_window->x == xwl_output->x &&
+ xwl_window->y == xwl_output->y &&
+ xwl_window->width == emulated_mode->width &&
+ xwl_window->height == emulated_mode->height) {
+
+ *emulated_mode_ret = emulated_mode;
+ *xwl_output_ret = xwl_output;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static void
+xwl_window_check_resolution_change_emulation(struct xwl_window *xwl_window)
+{
+ struct xwl_emulated_mode *emulated_mode;
+ struct xwl_output *xwl_output;
+
+ if (xwl_window_should_enable_viewport(xwl_window, &xwl_output, &emulated_mode))
+ xwl_window_enable_viewport(xwl_window, xwl_output, emulated_mode);
+ else if (xwl_window_has_viewport_enabled(xwl_window))
+ xwl_window_disable_viewport(xwl_window);
+}
+
+void
+xwl_screen_check_resolution_change_emulation(struct xwl_screen *xwl_screen)
+{
+ struct xwl_window *xwl_window;
+
+ xorg_list_for_each_entry(xwl_window, &xwl_screen->window_list, link_window)
+ xwl_window_check_resolution_change_emulation(xwl_window);
+}
+
static void
xwl_window_init_allow_commits(struct xwl_window *xwl_window)
{
@@ -569,6 +730,8 @@ ensure_surface_for_window(WindowPtr window)
xwl_window->xwl_screen = xwl_screen;
xwl_window->window = window;
+ xwl_window->width = window->drawable.width;
+ xwl_window->height = window->drawable.height;
xwl_window->surface = wl_compositor_create_surface(xwl_screen->compositor);
if (xwl_window->surface == NULL) {
ErrorF("wl_display_create_surface failed\n");
@@ -610,6 +773,7 @@ ensure_surface_for_window(WindowPtr window)
dixSetPrivate(&window->devPrivates, &xwl_window_private_key, xwl_window);
xorg_list_init(&xwl_window->link_damage);
+ xorg_list_add(&xwl_window->link_window, &xwl_screen->window_list);
xwl_window_init_allow_commits(xwl_window);
@@ -704,8 +868,12 @@ xwl_unrealize_window(WindowPtr window)
if (!xwl_window)
return ret;
+ if (xwl_window_has_viewport_enabled(xwl_window))
+ xwl_window_disable_viewport(xwl_window);
+
wl_surface_destroy(xwl_window->surface);
xorg_list_del(&xwl_window->link_damage);
+ xorg_list_del(&xwl_window->link_window);
unregister_damage(window);
if (xwl_window->frame_callback)
@@ -743,6 +911,33 @@ xwl_set_window_pixmap(WindowPtr window,
ensure_surface_for_window(window);
}
+static void
+xwl_resize_window(WindowPtr window,
+ int x, int y,
+ unsigned int width, unsigned int height,
+ WindowPtr sib)
+{
+ ScreenPtr screen = window->drawable.pScreen;
+ struct xwl_screen *xwl_screen;
+ struct xwl_window *xwl_window;
+
+ xwl_screen = xwl_screen_get(screen);
+ xwl_window = xwl_window_get(window);
+
+ screen->ResizeWindow = xwl_screen->ResizeWindow;
+ (*screen->ResizeWindow) (window, x, y, width, height, sib);
+ xwl_screen->ResizeWindow = screen->ResizeWindow;
+ screen->ResizeWindow = xwl_resize_window;
+
+ if (xwl_window) {
+ xwl_window->x = x;
+ xwl_window->y = y;
+ xwl_window->width = width;
+ xwl_window->height = height;
+ xwl_window_check_resolution_change_emulation(xwl_window);
+ }
+}
+
static void
frame_callback(void *data,
struct wl_callback *callback,
@@ -1158,6 +1353,7 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
xorg_list_init(&xwl_screen->output_list);
xorg_list_init(&xwl_screen->seat_list);
xorg_list_init(&xwl_screen->damage_window_list);
+ xorg_list_init(&xwl_screen->window_list);
xwl_screen->depth = 24;
xwl_screen->display = wl_display_connect(NULL);
@@ -1256,6 +1452,9 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
xwl_screen->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = xwl_close_screen;
+ xwl_screen->ResizeWindow = pScreen->ResizeWindow;
+ pScreen->ResizeWindow = xwl_resize_window;
+
if (xwl_screen->rootless) {
xwl_screen->SetWindowPixmap = pScreen->SetWindowPixmap;
pScreen->SetWindowPixmap = xwl_set_window_pixmap;
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index d0e87a89d..b52de11d2 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -135,10 +135,12 @@ struct xwl_screen {
DestroyWindowProcPtr DestroyWindow;
XYToWindowProcPtr XYToWindow;
SetWindowPixmapProcPtr SetWindowPixmap;
+ ResizeWindowProcPtr ResizeWindow;
struct xorg_list output_list;
struct xorg_list seat_list;
struct xorg_list damage_window_list;
+ struct xorg_list window_list;
int wayland_fd;
struct wl_display *display;
@@ -179,9 +181,13 @@ struct xwl_screen {
struct xwl_window {
struct xwl_screen *xwl_screen;
struct wl_surface *surface;
+ struct wp_viewport *viewport;
+ int32_t x, y, width, height;
+ float scale_x, scale_y;
struct wl_shell_surface *shell_surface;
WindowPtr window;
struct xorg_list link_damage;
+ struct xorg_list link_window;
struct wl_callback *frame_callback;
Bool allow_commits;
#ifdef GLAMOR_HAS_GBM
@@ -408,6 +414,9 @@ Bool xwl_screen_init_cursor(struct xwl_screen *xwl_screen);
struct xwl_screen *xwl_screen_get(ScreenPtr screen);
Bool xwl_screen_has_resolution_change_emulation(struct xwl_screen *xwl_screen);
+struct xwl_output *xwl_screen_get_first_output(struct xwl_screen *xwl_screen);
+void xwl_screen_check_resolution_change_emulation(struct xwl_screen *xwl_screen);
+Bool xwl_window_has_viewport_enabled(struct xwl_window *xwl_window);
void xwl_tablet_tool_set_cursor(struct xwl_tablet_tool *tool);
void xwl_seat_set_cursor(struct xwl_seat *xwl_seat);
@@ -441,6 +450,12 @@ void xwl_output_remove(struct xwl_output *xwl_output);
struct xwl_emulated_mode *xwl_output_get_emulated_mode_for_client(
struct xwl_output *xwl_output, ClientPtr client);
+RRModePtr xwl_output_find_mode(struct xwl_output *xwl_output,
+ int32_t width, int32_t height);
+void xwl_output_set_emulated_mode(struct xwl_output *xwl_output,
+ ClientPtr client, RRModePtr mode,
+ Bool from_vidmode);
+
RRModePtr xwayland_cvt(int HDisplay, int VDisplay,
float VRefresh, Bool Reduced, Bool Interlaced);
--
2.23.0

View File

@ -0,0 +1,100 @@
From 1ea054bda6618025838c3afb052080b749582454 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Mon, 8 Jul 2019 14:00:27 +0200
Subject: [PATCH xserver 09/14] xwayland: Add xwlRRModeToDisplayMode() helper
function
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This is a preparation patch for adding emulated mode/resolution change
support to Xwayland's XF86 vidmode extension emulation, using the
Wayland viewport extension.
Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
Acked-by: Michel Dänzer <mdaenzer@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/xwayland/xwayland-vidmode.c | 51 +++++++++++++++++++---------------
1 file changed, 28 insertions(+), 23 deletions(-)
diff --git a/hw/xwayland/xwayland-vidmode.c b/hw/xwayland/xwayland-vidmode.c
index 0bcd11401..a59c9f6a9 100644
--- a/hw/xwayland/xwayland-vidmode.c
+++ b/hw/xwayland/xwayland-vidmode.c
@@ -78,13 +78,37 @@ mode_refresh(const xRRModeInfo *mode_info)
return rate;
}
+static void
+xwlRRModeToDisplayMode(RRModePtr rrmode, DisplayModePtr mode)
+{
+ const xRRModeInfo *mode_info = &rrmode->mode;
+
+ mode->next = mode;
+ mode->prev = mode;
+ mode->name = "";
+ mode->VScan = 1;
+ mode->Private = NULL;
+ mode->HDisplay = mode_info->width;
+ mode->HSyncStart = mode_info->hSyncStart;
+ mode->HSyncEnd = mode_info->hSyncEnd;
+ mode->HTotal = mode_info->hTotal;
+ mode->HSkew = mode_info->hSkew;
+ mode->VDisplay = mode_info->height;
+ mode->VSyncStart = mode_info->vSyncStart;
+ mode->VSyncEnd = mode_info->vSyncEnd;
+ mode->VTotal = mode_info->vTotal;
+ mode->Flags = mode_info->modeFlags;
+ mode->Clock = mode_info->dotClock / 1000.0;
+ mode->VRefresh = mode_refresh(mode_info); /* Or RRVerticalRefresh() */
+ mode->HSync = mode_hsync(mode_info);
+}
+
static Bool
xwlVidModeGetCurrentModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock)
{
DisplayModePtr pMod;
RROutputPtr output;
RRCrtcPtr crtc;
- xRRModeInfo rrmode;
pMod = dixLookupPrivate(&pScreen->devPrivates, xwlVidModePrivateKey);
if (pMod == NULL)
@@ -98,30 +122,11 @@ xwlVidModeGetCurrentModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotCl
if (crtc == NULL)
return FALSE;
- rrmode = crtc->mode->mode;
-
- pMod->next = pMod;
- pMod->prev = pMod;
- pMod->name = "";
- pMod->VScan = 1;
- pMod->Private = NULL;
- pMod->HDisplay = rrmode.width;
- pMod->HSyncStart = rrmode.hSyncStart;
- pMod->HSyncEnd = rrmode.hSyncEnd;
- pMod->HTotal = rrmode.hTotal;
- pMod->HSkew = rrmode.hSkew;
- pMod->VDisplay = rrmode.height;
- pMod->VSyncStart = rrmode.vSyncStart;
- pMod->VSyncEnd = rrmode.vSyncEnd;
- pMod->VTotal = rrmode.vTotal;
- pMod->Flags = rrmode.modeFlags;
- pMod->Clock = rrmode.dotClock / 1000.0;
- pMod->VRefresh = mode_refresh(&rrmode); /* Or RRVerticalRefresh() */
- pMod->HSync = mode_hsync(&rrmode);
- *mode = pMod;
+ xwlRRModeToDisplayMode(crtc->mode, pMod);
+ *mode = pMod;
if (dotClock != NULL)
- *dotClock = rrmode.dotClock / 1000.0;
+ *dotClock = pMod->Clock;
return TRUE;
}
--
2.23.0

View File

@ -0,0 +1,192 @@
From 9edd8e37b5e2659a71b05dabed45fd7c3447de79 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Mon, 8 Jul 2019 18:35:27 +0200
Subject: [PATCH xserver 10/14] xwayland: Add xwlVidModeGetCurrentRRMode helper
to the vidmode code
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
crtc->mode reflects the mode set through the xrandr extension, once we
add support for also changing the mode through the vidmode extension this
will no longer correctly reflect the emulated resolution.
Add a new xwlVidModeGetCurrentRRMode helper which determines the mode by
looking at the emulated_mode instead.
Likewise add a xwlVidModeGetRRMode helper and use that in
xwlVidModeCheckModeForMonitor/xwlVidModeCheckModeForDriver to allow any
mode listed in the randr_output's mode list.
This is a preparation patch for adding emulated mode/resolution change
support to Xwayland's XF86 vidmode extension emulation.
Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
Acked-by: Michel Dänzer <mdaenzer@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/xwayland/xwayland-vidmode.c | 90 +++++++++++++++++++++-------------
1 file changed, 56 insertions(+), 34 deletions(-)
diff --git a/hw/xwayland/xwayland-vidmode.c b/hw/xwayland/xwayland-vidmode.c
index a59c9f6a9..e9aea7269 100644
--- a/hw/xwayland/xwayland-vidmode.c
+++ b/hw/xwayland/xwayland-vidmode.c
@@ -103,26 +103,56 @@ xwlRRModeToDisplayMode(RRModePtr rrmode, DisplayModePtr mode)
mode->HSync = mode_hsync(mode_info);
}
+static RRModePtr
+xwlVidModeGetRRMode(ScreenPtr pScreen, int32_t width, int32_t height)
+{
+ RROutputPtr output = RRFirstOutput(pScreen);
+
+ if (output == NULL)
+ return NULL;
+
+ return xwl_output_find_mode(output->devPrivate, width, height);
+}
+
+static RRModePtr
+xwlVidModeGetCurrentRRMode(ScreenPtr pScreen)
+{
+ struct xwl_emulated_mode *emulated_mode;
+ struct xwl_output *xwl_output;
+ RROutputPtr output;
+
+ output = RRFirstOutput(pScreen);
+ if (output == NULL)
+ return NULL;
+
+ xwl_output = output->devPrivate;
+ emulated_mode =
+ xwl_output_get_emulated_mode_for_client(xwl_output, GetCurrentClient());
+
+ if (emulated_mode) {
+ return xwl_output_find_mode(xwl_output,
+ emulated_mode->width,
+ emulated_mode->height);
+ } else {
+ return xwl_output_find_mode(xwl_output, -1, -1);
+ }
+}
+
static Bool
xwlVidModeGetCurrentModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock)
{
DisplayModePtr pMod;
- RROutputPtr output;
- RRCrtcPtr crtc;
+ RRModePtr rrmode;
pMod = dixLookupPrivate(&pScreen->devPrivates, xwlVidModePrivateKey);
if (pMod == NULL)
return FALSE;
- output = RRFirstOutput(pScreen);
- if (output == NULL)
- return FALSE;
-
- crtc = output->crtc;
- if (crtc == NULL)
+ rrmode = xwlVidModeGetCurrentRRMode(pScreen);
+ if (rrmode == NULL)
return FALSE;
- xwlRRModeToDisplayMode(crtc->mode, pMod);
+ xwlRRModeToDisplayMode(rrmode, pMod);
*mode = pMod;
if (dotClock != NULL)
@@ -135,9 +165,10 @@ static vidMonitorValue
xwlVidModeGetMonitorValue(ScreenPtr pScreen, int valtyp, int indx)
{
vidMonitorValue ret = { NULL, };
- DisplayModePtr pMod;
+ RRModePtr rrmode;
- if (!xwlVidModeGetCurrentModeline(pScreen, &pMod, NULL))
+ rrmode = xwlVidModeGetCurrentRRMode(pScreen);
+ if (rrmode == NULL)
return ret;
switch (valtyp) {
@@ -155,11 +186,11 @@ xwlVidModeGetMonitorValue(ScreenPtr pScreen, int valtyp, int indx)
break;
case VIDMODE_MON_HSYNC_LO:
case VIDMODE_MON_HSYNC_HI:
- ret.f = 100.0 * pMod->HSync;
+ ret.f = mode_hsync(&rrmode->mode) * 100.0;
break;
case VIDMODE_MON_VREFRESH_LO:
case VIDMODE_MON_VREFRESH_HI:
- ret.f = 100.0 * pMod->VRefresh;
+ ret.f = mode_refresh(&rrmode->mode) * 100.0;
break;
}
return ret;
@@ -168,13 +199,13 @@ xwlVidModeGetMonitorValue(ScreenPtr pScreen, int valtyp, int indx)
static int
xwlVidModeGetDotClock(ScreenPtr pScreen, int Clock)
{
- DisplayModePtr pMod;
+ RRModePtr rrmode;
- if (!xwlVidModeGetCurrentModeline(pScreen, &pMod, NULL))
+ rrmode = xwlVidModeGetCurrentRRMode(pScreen);
+ if (rrmode == NULL)
return 0;
- return pMod->Clock;
-
+ return rrmode->mode.dotClock / 1000.0;
}
static int
@@ -272,14 +303,15 @@ xwlVidModeLockZoom(ScreenPtr pScreen, Bool lock)
static ModeStatus
xwlVidModeCheckModeForMonitor(ScreenPtr pScreen, DisplayModePtr mode)
{
- DisplayModePtr pMod;
+ RRModePtr rrmode;
- /* This should not happen */
- if (!xwlVidModeGetCurrentModeline(pScreen, &pMod, NULL))
+ rrmode = xwlVidModeGetRRMode(pScreen, mode->HDisplay, mode->VDisplay);
+ if (rrmode == NULL)
return MODE_ERROR;
/* Only support mode with the same HSync/VRefresh as we advertise */
- if (mode->HSync == pMod->HSync && mode->VRefresh == pMod->VRefresh)
+ if (mode->HSync == mode_hsync(&rrmode->mode) &&
+ mode->VRefresh == mode_refresh(&rrmode->mode))
return MODE_OK;
/* All the rest is unsupported - If we want to succeed, return MODE_OK instead */
@@ -289,20 +321,10 @@ xwlVidModeCheckModeForMonitor(ScreenPtr pScreen, DisplayModePtr mode)
static ModeStatus
xwlVidModeCheckModeForDriver(ScreenPtr pScreen, DisplayModePtr mode)
{
- DisplayModePtr pMod;
-
- /* This should not happen */
- if (!xwlVidModeGetCurrentModeline(pScreen, &pMod, NULL))
- return MODE_ERROR;
-
- if (mode->HTotal != pMod->HTotal)
- return MODE_BAD_HVALUE;
+ RRModePtr rrmode;
- if (mode->VTotal != pMod->VTotal)
- return MODE_BAD_VVALUE;
-
- /* Unsupported for now, but pretend it works */
- return MODE_OK;
+ rrmode = xwlVidModeGetRRMode(pScreen, mode->HDisplay, mode->VDisplay);
+ return rrmode ? MODE_OK : MODE_ERROR;
}
static void
--
2.23.0

View File

@ -0,0 +1,235 @@
From 984691516d78284a8ab63058b0c1d3c68666a7d9 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Tue, 9 Jul 2019 09:31:13 +0200
Subject: [PATCH xserver 11/14] xwayland: Add vidmode mode changing emulation
support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add support for fake mode changes using viewport, for apps which want to
change the resolution when going fullscreen.
Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
Acked-by: Michel Dänzer <mdaenzer@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/xwayland/xwayland-vidmode.c | 130 ++++++++++++++++++++++-----------
1 file changed, 86 insertions(+), 44 deletions(-)
diff --git a/hw/xwayland/xwayland-vidmode.c b/hw/xwayland/xwayland-vidmode.c
index e9aea7269..56aac693a 100644
--- a/hw/xwayland/xwayland-vidmode.c
+++ b/hw/xwayland/xwayland-vidmode.c
@@ -106,26 +106,25 @@ xwlRRModeToDisplayMode(RRModePtr rrmode, DisplayModePtr mode)
static RRModePtr
xwlVidModeGetRRMode(ScreenPtr pScreen, int32_t width, int32_t height)
{
- RROutputPtr output = RRFirstOutput(pScreen);
+ struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
+ struct xwl_output *xwl_output = xwl_screen_get_first_output(xwl_screen);
- if (output == NULL)
+ if (!xwl_output)
return NULL;
- return xwl_output_find_mode(output->devPrivate, width, height);
+ return xwl_output_find_mode(xwl_output, width, height);
}
static RRModePtr
xwlVidModeGetCurrentRRMode(ScreenPtr pScreen)
{
+ struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
+ struct xwl_output *xwl_output = xwl_screen_get_first_output(xwl_screen);
struct xwl_emulated_mode *emulated_mode;
- struct xwl_output *xwl_output;
- RROutputPtr output;
- output = RRFirstOutput(pScreen);
- if (output == NULL)
+ if (!xwl_output)
return NULL;
- xwl_output = output->devPrivate;
emulated_mode =
xwl_output_get_emulated_mode_for_client(xwl_output, GetCurrentClient());
@@ -199,39 +198,79 @@ xwlVidModeGetMonitorValue(ScreenPtr pScreen, int valtyp, int indx)
static int
xwlVidModeGetDotClock(ScreenPtr pScreen, int Clock)
{
- RRModePtr rrmode;
-
- rrmode = xwlVidModeGetCurrentRRMode(pScreen);
- if (rrmode == NULL)
- return 0;
-
- return rrmode->mode.dotClock / 1000.0;
+ return Clock;
}
static int
xwlVidModeGetNumOfClocks(ScreenPtr pScreen, Bool *progClock)
{
- return 1;
+ /* We emulate a programmable clock, rather then a fixed set of clocks */
+ *progClock = TRUE;
+ return 0;
}
static Bool
xwlVidModeGetClocks(ScreenPtr pScreen, int *Clocks)
{
- *Clocks = xwlVidModeGetDotClock(pScreen, 0);
-
- return TRUE;
+ return FALSE; /* Programmable clock, no clock list */
}
+/* GetFirstModeline and GetNextModeline are used from Xext/vidmode.c like this:
+ * if (pVidMode->GetFirstModeline(pScreen, &mode, &dotClock)) {
+ * do {
+ * ...
+ * if (...)
+ * break;
+ * } while (pVidMode->GetNextModeline(pScreen, &mode, &dotClock));
+ * }
+ * IOW our caller basically always loops over all the modes. There never is a
+ * return to the mainloop between GetFirstModeline and NextModeline calls where
+ * other parts of the server may change our state so we do not need to worry
+ * about xwl_output->randr_output->modes changing underneath us.
+ * Thus we can simply implement these two callbacks by storing the enumeration
+ * index in pVidMode->Next.
+ */
+
static Bool
xwlVidModeGetNextModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock)
{
- return FALSE;
+ struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
+ struct xwl_output *xwl_output = xwl_screen_get_first_output(xwl_screen);
+ VidModePtr pVidMode;
+ DisplayModePtr pMod;
+ intptr_t index;
+
+ pMod = dixLookupPrivate(&pScreen->devPrivates, xwlVidModePrivateKey);
+ pVidMode = VidModeGetPtr(pScreen);
+ if (xwl_output == NULL || pMod == NULL || pVidMode == NULL)
+ return FALSE;
+
+ index = (intptr_t)pVidMode->Next;
+ if (index >= xwl_output->randr_output->numModes)
+ return FALSE;
+ xwlRRModeToDisplayMode(xwl_output->randr_output->modes[index], pMod);
+ index++;
+ pVidMode->Next = (void *)index;
+
+ *mode = pMod;
+ if (dotClock != NULL)
+ *dotClock = pMod->Clock;
+
+ return TRUE;
}
static Bool
xwlVidModeGetFirstModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock)
{
- return xwlVidModeGetCurrentModeline(pScreen, mode, dotClock);
+ VidModePtr pVidMode;
+ intptr_t index = 0;
+
+ pVidMode = VidModeGetPtr(pScreen);
+ if (pVidMode == NULL)
+ return FALSE;
+
+ pVidMode->Next = (void *)index; /* 0 */
+ return xwlVidModeGetNextModeline(pScreen, mode, dotClock);
}
static Bool
@@ -251,37 +290,27 @@ xwlVidModeZoomViewport(ScreenPtr pScreen, int zoom)
static Bool
xwlVidModeSetViewPort(ScreenPtr pScreen, int x, int y)
{
- RROutputPtr output;
- RRCrtcPtr crtc;
+ struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
+ struct xwl_output *xwl_output = xwl_screen_get_first_output(xwl_screen);
- output = RRFirstOutput(pScreen);
- if (output == NULL)
- return FALSE;
-
- crtc = output->crtc;
- if (crtc == NULL)
+ if (!xwl_output)
return FALSE;
/* Support only default viewport */
- return (x == crtc->x && y == crtc->y);
+ return (x == xwl_output->x && y == xwl_output->y);
}
static Bool
xwlVidModeGetViewPort(ScreenPtr pScreen, int *x, int *y)
{
- RROutputPtr output;
- RRCrtcPtr crtc;
+ struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
+ struct xwl_output *xwl_output = xwl_screen_get_first_output(xwl_screen);
- output = RRFirstOutput(pScreen);
- if (output == NULL)
+ if (!xwl_output)
return FALSE;
- crtc = output->crtc;
- if (crtc == NULL)
- return FALSE;
-
- *x = crtc->x;
- *y = crtc->y;
+ *x = xwl_output->x;
+ *y = xwl_output->y;
return TRUE;
}
@@ -289,8 +318,19 @@ xwlVidModeGetViewPort(ScreenPtr pScreen, int *x, int *y)
static Bool
xwlVidModeSwitchMode(ScreenPtr pScreen, DisplayModePtr mode)
{
- /* Unsupported for now */
- return FALSE;
+ struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
+ struct xwl_output *xwl_output = xwl_screen_get_first_output(xwl_screen);
+ RRModePtr rrmode;
+
+ if (!xwl_output)
+ return FALSE;
+
+ rrmode = xwl_output_find_mode(xwl_output, mode->HDisplay, mode->VDisplay);
+ if (rrmode == NULL)
+ return FALSE;
+
+ xwl_output_set_emulated_mode(xwl_output, GetCurrentClient(), rrmode, TRUE);
+ return TRUE;
}
static Bool
@@ -344,8 +384,10 @@ xwlVidModeAddModeline(ScreenPtr pScreen, DisplayModePtr mode)
static int
xwlVidModeGetNumOfModes(ScreenPtr pScreen)
{
- /* We have only one mode */
- return 1;
+ struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
+ struct xwl_output *xwl_output = xwl_screen_get_first_output(xwl_screen);
+
+ return xwl_output ? xwl_output->randr_output->numModes : 0;
}
static Bool
--
2.23.0

View File

@ -0,0 +1,56 @@
From 912688326c0f9435660e86a2bdab049caa4b0e9f Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Mon, 26 Aug 2019 12:26:34 +0200
Subject: [PATCH xserver 12/14] xwayland: xwl_window_should_enable_viewport:
Add extra test
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Games based on the allegro gaming library or on ClanLib-1.0 do not size
their window to match the fullscreen resolution, instead they use a
window covering the entire screen, drawing only the fullscreen resolution
part of it.
This commit adds a check for these games, so that we correctly apply a
viewport to them making fullscreen work properly for these games under
Xwayland.
Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
Acked-by: Michel Dänzer <mdaenzer@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/xwayland/xwayland.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index ec1b7eee4..58252d2e8 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -636,6 +636,23 @@ xwl_window_should_enable_viewport(struct xwl_window *xwl_window,
}
}
+ /* 2. Test if the window uses override-redirect + vidmode
+ * and matches (fully covers) the entire screen.
+ * This path gets hit by: allegro4, ClanLib-1.0.
+ */
+ xwl_output = xwl_screen_get_first_output(xwl_screen);
+ emulated_mode = xwl_output_get_emulated_mode_for_client(xwl_output, owner);
+ if (xwl_output && xwl_window->window->overrideRedirect &&
+ emulated_mode && emulated_mode->from_vidmode &&
+ xwl_window->x == 0 && xwl_window->y == 0 &&
+ xwl_window->width == xwl_screen->width &&
+ xwl_window->height == xwl_screen->height) {
+
+ *emulated_mode_ret = emulated_mode;
+ *xwl_output_ret = xwl_output;
+ return TRUE;
+ }
+
return FALSE;
}
--
2.23.0

View File

@ -0,0 +1,204 @@
From d9f1d6f51f4c2d388214a675330b58ba2facb170 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Mon, 2 Sep 2019 17:32:45 +0200
Subject: [PATCH xserver 13/14] xwayland: Set _XWAYLAND_RANDR_EMU_MONITOR_RECTS
property for resolution emulation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Apps using randr to change the resolution when going fullscreen, in
combination with _NET_WM_STATE_FULLSCREEN to tell the window-manager (WM)
to make their window fullscreen, expect the WM to give the fullscreen window
the size of the emulated resolution as would happen when run under Xorg (*).
We need the WM to emulate this behavior for these apps to work correctly,
with Xwaylands resolution change emulation. For the WM to emulate this,
it needs to know about the emulated resolution for the Windows owning
client for each monitor.
This commit adds a _XWAYLAND_RANDR_EMU_MONITOR_RECTS property, which
contains 4 Cardinals (32 bit integers) per monitor with resolution
emulation info. Window-managers can use this to get the emulated
resolution for the client and size the window correctly.
*) Since under Xorg the resolution will actually be changed and after that
going fullscreen through NET_WM_STATE_FULLSCREEN will size the window to
be equal to the new resolution.
Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
Acked-by: Michel Dänzer <mdaenzer@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/xwayland/xwayland-output.c | 77 +++++++++++++++++++++++++++++++++++
hw/xwayland/xwayland.c | 23 +++++++++++
hw/xwayland/xwayland.h | 3 ++
3 files changed, 103 insertions(+)
diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
index 99ab1b288..20c254962 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -29,6 +29,7 @@
#include "xwayland.h"
#include <randrstr.h>
+#include <X11/Xatom.h>
#define DEFAULT_DPI 96
#define ALL_ROTATIONS (RR_Rotate_0 | \
@@ -428,6 +429,80 @@ xwl_output_find_mode(struct xwl_output *xwl_output,
return NULL;
}
+struct xwl_output_randr_emu_prop {
+ Atom atom;
+ uint32_t rects[XWL_CLIENT_MAX_EMULATED_MODES][4];
+ int rect_count;
+};
+
+static void
+xwl_output_randr_emu_prop(struct xwl_screen *xwl_screen, ClientPtr client,
+ struct xwl_output_randr_emu_prop *prop)
+{
+ static const char atom_name[] = "_XWAYLAND_RANDR_EMU_MONITOR_RECTS";
+ struct xwl_emulated_mode *emulated_mode;
+ struct xwl_output *xwl_output;
+ int index = 0;
+
+ prop->atom = MakeAtom(atom_name, strlen(atom_name), TRUE);
+
+ xorg_list_for_each_entry(xwl_output, &xwl_screen->output_list, link) {
+ emulated_mode = xwl_output_get_emulated_mode_for_client(xwl_output, client);
+ if (!emulated_mode)
+ continue;
+
+ prop->rects[index][0] = xwl_output->x;
+ prop->rects[index][1] = xwl_output->y;
+ prop->rects[index][2] = emulated_mode->width;
+ prop->rects[index][3] = emulated_mode->height;
+ index++;
+ }
+
+ prop->rect_count = index;
+}
+
+static void
+xwl_output_set_randr_emu_prop(WindowPtr window,
+ struct xwl_output_randr_emu_prop *prop)
+{
+ if (!xwl_window_is_toplevel(window))
+ return;
+
+ if (prop->rect_count) {
+ dixChangeWindowProperty(serverClient, window, prop->atom,
+ XA_CARDINAL, 32, PropModeReplace,
+ prop->rect_count * 4, prop->rects, TRUE);
+ } else {
+ DeleteProperty(serverClient, window, prop->atom);
+ }
+}
+
+static void
+xwl_output_set_randr_emu_prop_callback(void *resource, XID id, void *user_data)
+{
+ xwl_output_set_randr_emu_prop(resource, user_data);
+}
+
+static void
+xwl_output_set_randr_emu_props(struct xwl_screen *xwl_screen, ClientPtr client)
+{
+ struct xwl_output_randr_emu_prop prop = {};
+
+ xwl_output_randr_emu_prop(xwl_screen, client, &prop);
+ FindClientResourcesByType(client, RT_WINDOW,
+ xwl_output_set_randr_emu_prop_callback, &prop);
+}
+
+void
+xwl_output_set_window_randr_emu_props(struct xwl_screen *xwl_screen,
+ WindowPtr window)
+{
+ struct xwl_output_randr_emu_prop prop = {};
+
+ xwl_output_randr_emu_prop(xwl_screen, wClient(window), &prop);
+ xwl_output_set_randr_emu_prop(window, &prop);
+}
+
void
xwl_output_set_emulated_mode(struct xwl_output *xwl_output, ClientPtr client,
RRModePtr mode, Bool from_vidmode)
@@ -442,6 +517,8 @@ xwl_output_set_emulated_mode(struct xwl_output *xwl_output, ClientPtr client,
xwl_output_add_emulated_mode_for_client(xwl_output, client, mode, from_vidmode);
xwl_screen_check_resolution_change_emulation(xwl_output->xwl_screen);
+
+ xwl_output_set_randr_emu_props(xwl_output->xwl_screen, client);
}
static void
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 58252d2e8..75ff9f011 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -677,6 +677,27 @@ xwl_screen_check_resolution_change_emulation(struct xwl_screen *xwl_screen)
xwl_window_check_resolution_change_emulation(xwl_window);
}
+/* This checks if the passed in Window is a toplevel client window, note this
+ * returns false for window-manager decoration windows and returns true for
+ * the actual client top-level window even if it has been reparented to
+ * a window-manager decoration window.
+ */
+Bool
+xwl_window_is_toplevel(WindowPtr window)
+{
+ struct xwl_screen *xwl_screen = xwl_screen_get(window->drawable.pScreen);
+
+ if (xwl_screen_client_is_window_manager(xwl_screen, wClient(window)))
+ return FALSE;
+
+ /* CSD and override-redirect toplevel windows */
+ if (window_get_damage(window))
+ return TRUE;
+
+ /* Normal toplevel client windows, reparented to decoration window */
+ return (window->parent && window_get_damage(window->parent));
+}
+
static void
xwl_window_init_allow_commits(struct xwl_window *xwl_window)
{
@@ -838,6 +859,8 @@ xwl_realize_window(WindowPtr window)
return FALSE;
}
+ xwl_output_set_window_randr_emu_props(xwl_screen, window);
+
return ensure_surface_for_window(window);
}
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index b52de11d2..2d825ee8c 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -417,6 +417,7 @@ Bool xwl_screen_has_resolution_change_emulation(struct xwl_screen *xwl_screen);
struct xwl_output *xwl_screen_get_first_output(struct xwl_screen *xwl_screen);
void xwl_screen_check_resolution_change_emulation(struct xwl_screen *xwl_screen);
Bool xwl_window_has_viewport_enabled(struct xwl_window *xwl_window);
+Bool xwl_window_is_toplevel(WindowPtr window);
void xwl_tablet_tool_set_cursor(struct xwl_tablet_tool *tool);
void xwl_seat_set_cursor(struct xwl_seat *xwl_seat);
@@ -455,6 +456,8 @@ RRModePtr xwl_output_find_mode(struct xwl_output *xwl_output,
void xwl_output_set_emulated_mode(struct xwl_output *xwl_output,
ClientPtr client, RRModePtr mode,
Bool from_vidmode);
+void xwl_output_set_window_randr_emu_props(struct xwl_screen *xwl_screen,
+ WindowPtr window);
RRModePtr xwayland_cvt(int HDisplay, int VDisplay,
float VRefresh, Bool Reduced, Bool Interlaced);
--
2.23.0

View File

@ -0,0 +1,61 @@
From c392765d459bd2cac6e3f431c67d698bb905e0ab Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Mon, 7 Oct 2019 14:27:49 +0200
Subject: [PATCH xserver 14/14] xwayland: Fix emulated modes not being removed
when screen rotation is used
The code building the mode-list does the following to deal with screen
rotation:
if (need_rotate || xwl_output->rotation & (RR_Rotate_0 | RR_Rotate_180)) {
mode_width = xwl_output->width;
mode_height = xwl_output->height;
} else {
mode_width = xwl_output->height;
mode_height = xwl_output->width;
}
This means we need to do something similar in xwl_output_set_emulated_mode()
to determine if the mode being set is the actual (not-emulated) output mode
and we this should remove any emulated modes set by the client.
All callers of xwl_output_set_emulated_mode always pass a mode pointer
to a member of xwl_output->randr_output->modes, so we do not need to
duplicate this code, instead we can simply check that the passed in mode
is modes[0] which always is the actual output mode.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/xwayland/xwayland-output.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
index 20c254962..7d705d919 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -309,8 +309,11 @@ xwl_output_remove_emulated_mode_for_client(struct xwl_output *xwl_output,
struct xwl_emulated_mode *emulated_mode;
emulated_mode = xwl_output_get_emulated_mode_for_client(xwl_output, client);
- if (emulated_mode)
+ if (emulated_mode) {
+ DebugF("XWAYLAND: xwl_output_remove_emulated_mode: %dx%d\n",
+ emulated_mode->width, emulated_mode->height);
memset(emulated_mode, 0, sizeof(*emulated_mode));
+ }
}
/* From hw/xfree86/common/xf86DefModeSet.c with some obscure modes dropped */
@@ -511,7 +514,8 @@ xwl_output_set_emulated_mode(struct xwl_output *xwl_output, ClientPtr client,
from_vidmode ? "vidmode" : "randr",
mode->mode.width, mode->mode.height);
- if (mode->mode.width == xwl_output->width && mode->mode.height == xwl_output->height)
+ /* modes[0] is the actual (not-emulated) output mode */
+ if (mode == xwl_output->randr_output->modes[0])
xwl_output_remove_emulated_mode_for_client(xwl_output, client);
else
xwl_output_add_emulated_mode_for_client(xwl_output, client, mode, from_vidmode);
--
2.23.0

View File

@ -0,0 +1,46 @@
From 01629caef21b77cfabc052408eb04699e4fa5143 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Mon, 4 Nov 2019 11:46:49 +0100
Subject: [PATCH xserver 15/17] xwayland: Call
xwl_window_check_resolution_change_emulation() on newly created O-R windows
Some clients, which use vidmode to change the resolution when going fullscreen,
create an override-redirect window and never trigger the screen->ResizeWindow
callback we rely on to do the xwl_window_check_resolution_change_emulation().
This causes us to not apply a viewport to them, causing the fullscreen window
to not fill the entire monitor.
This commit adds a call to xwl_window_check_resolution_change_emulation()
at the end of ensure_surface_for_window() to fix this. Note that
ensure_surface_for_window() exits early without creating an xwl_window
for new windows which will not be backed by a wayland surface and which
thus will not have an xwl_window.
This fixes ClanLib-0.6.x and alleggl-4.4.x using apps not properly
fullscreening.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/xwayland/xwayland.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 75ff9f011..ed1d671ff 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -815,6 +815,11 @@ ensure_surface_for_window(WindowPtr window)
xwl_window_init_allow_commits(xwl_window);
+ if (!xwl_screen_client_is_window_manager(xwl_screen, wClient(window))) {
+ /* CSD or O-R toplevel window, check viewport on creation */
+ xwl_window_check_resolution_change_emulation(xwl_window);
+ }
+
return TRUE;
err_surf:
--
2.23.0

View File

@ -0,0 +1,65 @@
From 2db2fcb97bd148476817634486cb384a1f623fa9 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Mon, 4 Nov 2019 14:32:29 +0100
Subject: [PATCH xserver 16/17] xwayland: Fix setting of
_XWAYLAND_RANDR_EMU_MONITOR_RECTS prop on new windows
For window-manager managed windows, xwl_realize_window is only called for
the window-manager's decoration window and not for the actual client window
on which we should set the _XWAYLAND_RANDR_EMU_MONITOR_RECTS prop.
Usualy this is not a problem since we walk all client windows to update
the property when the resolution is changed through a randr call.
But for apps which first do the randr change and only then create their
window this does not work, and our xwl_output_set_window_randr_emu_props
call in xwl_realize_window is a no-op as that is only called for the wm
decoration window and not for the actual client's window.
This commit fixes this by making ensure_surface_for_window() call
xwl_output_set_window_randr_emu_props on the first and only child of
window-manager managed windows.
Note this also removes the non-functional xwl_output_set_window_randr_emu_props
call from xwl_realize_window, which was intended to do this, but does not
work.
This fixes apps using the ogre3d library always running at the
monitors native resolution.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/xwayland/xwayland.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index ed1d671ff..1ce29c51c 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -815,7 +815,13 @@ ensure_surface_for_window(WindowPtr window)
xwl_window_init_allow_commits(xwl_window);
- if (!xwl_screen_client_is_window_manager(xwl_screen, wClient(window))) {
+ /* When a new windom-manager decoration window is realized, then the randr
+ * emulation props have not been set on the managed client window yet.
+ */
+ if (xwl_screen_client_is_window_manager(xwl_screen, wClient(window))) {
+ if (window->firstChild && window->firstChild == window->lastChild)
+ xwl_output_set_window_randr_emu_props(xwl_screen, window->firstChild);
+ } else {
/* CSD or O-R toplevel window, check viewport on creation */
xwl_window_check_resolution_change_emulation(xwl_window);
}
@@ -864,8 +870,6 @@ xwl_realize_window(WindowPtr window)
return FALSE;
}
- xwl_output_set_window_randr_emu_props(xwl_screen, window);
-
return ensure_surface_for_window(window);
}
--
2.23.0

View File

@ -0,0 +1,47 @@
From f73305cc415d2fd464aae4b0dc72558fd1b6bd81 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Mon, 4 Nov 2019 15:01:18 +0100
Subject: [PATCH xserver 17/17] xwayland: Remove unnecessary
xwl_window_is_toplevel() check from xwl_output_set_window_randr_emu_props()
Since the recent fix to call xwl_output_set_window_randr_emu_props() from
ensure_surface_for_window(), it is now only called on a toplevel window,
so the is-toplevel check is not necessary for the
xwl_output_set_window_randr_emu_props() case.
This commit moves the check to xwl_output_set_randr_emu_prop_callback()
so that we only do it when we are walking over all Windows of a client
to update the property on a change of the emulated resolution.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/xwayland/xwayland-output.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
index 7d705d919..084b669e4 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -468,9 +468,6 @@ static void
xwl_output_set_randr_emu_prop(WindowPtr window,
struct xwl_output_randr_emu_prop *prop)
{
- if (!xwl_window_is_toplevel(window))
- return;
-
if (prop->rect_count) {
dixChangeWindowProperty(serverClient, window, prop->atom,
XA_CARDINAL, 32, PropModeReplace,
@@ -483,7 +480,8 @@ xwl_output_set_randr_emu_prop(WindowPtr window,
static void
xwl_output_set_randr_emu_prop_callback(void *resource, XID id, void *user_data)
{
- xwl_output_set_randr_emu_prop(resource, user_data);
+ if (xwl_window_is_toplevel(resource))
+ xwl_output_set_randr_emu_prop(resource, user_data);
}
static void
--
2.23.0

View File

@ -46,7 +46,7 @@
Summary: X.Org X11 X server
Name: xorg-x11-server
Version: 1.20.5
Release: 7%{?gitdate:.%{gitdate}}%{?dist}
Release: 8%{?gitdate:.%{gitdate}}%{?dist}
URL: http://www.x.org
License: MIT
@ -137,6 +137,25 @@ Patch44: 0013-xwayland-Separate-DamagePtr-into-separate-window-dat.patch
Patch45: 0014-xwayland-Refactor-surface-creation-into-a-separate-f.patch
Patch46: 0015-xwayland-Handle-the-case-of-windows-being-realized-b.patch
# Backported Xwayland randr resolution change emulation support
Patch47: 0001-dix-Add-GetCurrentClient-helper.patch
Patch48: 0002-xwayland-Add-wp_viewport-wayland-extension-support.patch
Patch49: 0003-xwayland-Use-buffer_damage-instead-of-surface-damage.patch
Patch50: 0004-xwayland-Add-fake-output-modes-to-xrandr-output-mode.patch
Patch51: 0005-xwayland-Use-RandR-1.2-interface-rev-2.patch
Patch52: 0006-xwayland-Add-per-client-private-data.patch
Patch53: 0007-xwayland-Add-support-for-storing-per-client-per-outp.patch
Patch54: 0008-xwayland-Add-support-for-randr-resolution-change-emu.patch
Patch55: 0009-xwayland-Add-xwlRRModeToDisplayMode-helper-function.patch
Patch56: 0010-xwayland-Add-xwlVidModeGetCurrentRRMode-helper-to-th.patch
Patch57: 0011-xwayland-Add-vidmode-mode-changing-emulation-support.patch
Patch58: 0012-xwayland-xwl_window_should_enable_viewport-Add-extra.patch
Patch59: 0013-xwayland-Set-_XWAYLAND_RANDR_EMU_MONITOR_RECTS-prope.patch
Patch60: 0014-xwayland-Fix-emulated-modes-not-being-removed-when-s.patch
Patch61: 0015-xwayland-Call-xwl_window_check_resolution_change_emu.patch
Patch62: 0016-xwayland-Fix-setting-of-_XWAYLAND_RANDR_EMU_MONITOR_.patch
Patch63: 0017-xwayland-Remove-unnecessary-xwl_window_is_toplevel-c.patch
BuildRequires: systemtap-sdt-devel
BuildRequires: git
BuildRequires: automake autoconf libtool pkgconfig
@ -561,6 +580,9 @@ find %{inst_srcdir}/hw/xfree86 -name \*.c -delete
%changelog
* Mon Nov 4 2019 Hans de Goede <hdegoede@redhat.com> - 1.20.5-8
- Backport Xwayland randr resolution change emulation support
* Thu Aug 29 2019 Olivier Fourdan <ofourdan@redhat.com> 1.20.5-7
- Pick latest fixes from xserver stable branch upstream (rhbz#1729925)