Merged update from upstream sources

This is an automated DistroBaker update from upstream sources.
If you do not know what this is about or would like to opt out,
contact the OSCI team.

Source: https://src.fedoraproject.org/rpms/xorg-x11-server.git#b1458e4567cd8795d5d660be512877750cde9c2f
This commit is contained in:
DistroBaker 2021-02-01 14:33:51 +00:00
parent 39b2cb441e
commit f5fdf1a56d
26 changed files with 8 additions and 3142 deletions

View File

@ -1,116 +0,0 @@
From a815e5f51f75684a53d8fa14b596e03b738cd281 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/25] 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>
(cherry picked from commit 834a467af978ac7a24ed17b8c8e58b6cddb4faf9)
---
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 a33bfaa9e..2b1cf1a74 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.28.0

View File

@ -1,119 +0,0 @@
From 0a3046286e69b171c319ff419c94cf62929246bf 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/25] 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>
(cherry picked from commit 47bba4625339592d08b375bcd8e51029c0000850)
---
hw/xwayland/Makefile.am | 9 ++++++++-
hw/xwayland/meson.build | 3 +++
hw/xwayland/xwayland.c | 3 +++
hw/xwayland/xwayland.h | 2 ++
4 files changed, 16 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 b353167c3..a70c1002f 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -912,6 +912,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 b9495b313..91ae21eeb 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.28.0

View File

@ -1,160 +0,0 @@
From 30859f64d1718d1476648dcddbb3d81c2f932828 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/25] 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>
(cherry picked from commit 7c6f17790d3aedb164481264b0f05a8a14103731)
---
hw/xwayland/xwayland-cursor.c | 12 ++++++------
hw/xwayland/xwayland-present.c | 10 +++++-----
hw/xwayland/xwayland.c | 29 +++++++++++++++++++++++------
hw/xwayland/xwayland.h | 3 +++
4 files changed, 37 insertions(+), 17 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 d177abdd8..f4027f91e 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -505,11 +505,11 @@ xwl_present_flip(WindowPtr present_window,
/* Realign timer */
xwl_present_reset_timer(xwl_present_window);
- wl_surface_damage(xwl_window->surface,
- damage_box->x1 - present_window->drawable.x,
- damage_box->y1 - present_window->drawable.y,
- damage_box->x2 - damage_box->x1,
- damage_box->y2 - damage_box->y1);
+ xwl_surface_damage(xwl_window->xwl_screen, xwl_window->surface,
+ damage_box->x1 - present_window->drawable.x,
+ damage_box->y1 - present_window->drawable.y,
+ 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 a70c1002f..811257b00 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -792,6 +792,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)
{
@@ -828,13 +838,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_create_frame_callback(xwl_window);
@@ -893,8 +905,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 91ae21eeb..1244d2e91 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -382,6 +382,9 @@ struct xwl_output {
void xwl_window_create_frame_callback(struct xwl_window *xwl_window);
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);
void xwl_screen_roundtrip (struct xwl_screen *xwl_screen);
--
2.28.0

View File

@ -1,207 +0,0 @@
From 32987e08e7f1e79ee50ce032cc6c1b6d28e6a50d 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/25] 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>
(cherry picked from commit 0d656d796071fb637e4969ea800855fe5d1c9728)
---
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 ae646c663..4036ba681 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -208,14 +208,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 */
@@ -234,12 +330,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 811257b00..e84515f94 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -154,6 +154,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 1244d2e91..200e18a8d 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -391,6 +391,7 @@ void xwl_screen_roundtrip (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.28.0

View File

@ -1,139 +0,0 @@
From 09dcf01f5ea8d1f828a58e54edd608e6918d0b59 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/25] 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>
(cherry picked from commit e89872f51aa834fa9d94a4ca4822f03b0341ab4f)
---
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 4036ba681..633ebb89e 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -524,12 +524,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)
@@ -543,7 +611,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.28.0

View File

@ -1,80 +0,0 @@
From ca0616ca4ca1badff2674fa5db8f290935b81e7f 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/25] 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>
(cherry picked from commit 905cb8b9e27add5f49a45fe167a0005bf05218bc)
---
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 e84515f94..f422cfc29 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -137,11 +137,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)
{
@@ -1145,6 +1152,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 200e18a8d..19626d394 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -379,8 +379,13 @@ struct xwl_output {
Bool xdg_output_done;
};
+struct xwl_client {
+};
+
void xwl_window_create_frame_callback(struct xwl_window *xwl_window);
+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.28.0

View File

@ -1,149 +0,0 @@
From 4bc5480d2e63cceecdc18b4bfda4fb4624f8fb43 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/25] 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>
(cherry picked from commit aca0a588eb40a5e6669094a2ab7f71ca0ba06b16)
---
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 633ebb89e..64794dee7 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -208,6 +208,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 19626d394..c886d77e9 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -379,7 +379,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];
};
void xwl_window_create_frame_callback(struct xwl_window *xwl_window);
@@ -427,6 +441,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.28.0

View File

@ -1,462 +0,0 @@
From 2f2a6b8556bd104740d76126640abcfe4705047c 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/25] 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>
(cherry picked from commit d99b9ff0f237d15e7eb507484493c73b393d5dba)
---
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 a05d178ff..7d75a8f54 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -488,6 +488,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 64794dee7..e09d00108 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -371,6 +371,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)
{
@@ -613,21 +649,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 f422cfc29..87870a5f1 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -178,6 +178,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)
@@ -501,6 +518,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)
{
@@ -571,6 +732,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");
@@ -612,6 +775,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);
#ifdef GLAMOR_HAS_GBM
xorg_list_init(&xwl_window->frame_callback_list);
@@ -705,8 +869,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)
@@ -756,6 +924,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,
@@ -1233,6 +1428,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;
if (!monitorResolution)
@@ -1332,6 +1528,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 c886d77e9..36c4c4c8b 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
@@ -411,6 +417,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);
@@ -444,6 +453,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.28.0

View File

@ -1,101 +0,0 @@
From aedd71a61ac2d78c347180e7d87e5918b795609e 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/25] 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>
(cherry picked from commit 43c80078126f6f33c6ab7d3cf4668733bde03366)
---
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 d25d1aca1..428af716d 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.28.0

View File

@ -1,193 +0,0 @@
From 719c1d2ef99784043883787d04afc0437f3a9b8f 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/25] 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>
(cherry picked from commit bcad1b813a04b9f3ff225f57a4baad09bd6315b9)
---
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 428af716d..7cf982fcc 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.28.0

View File

@ -1,236 +0,0 @@
From 98e6cadf2ba8490c303cdc94106baf3f31006299 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/25] 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>
(cherry picked from commit 38de6260816674b5430144cc38a8a27d93d1bf19)
---
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 7cf982fcc..99a4d2c92 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.28.0

View File

@ -1,57 +0,0 @@
From 3d359d03573dee270b72f0cea1ea9061c2c886c3 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/25] 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>
(cherry picked from commit 0c305dbff8a44f3fa3d6aefd372a967029a7a527)
---
hw/xwayland/xwayland.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 87870a5f1..9175396f7 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -638,6 +638,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.28.0

View File

@ -1,205 +0,0 @@
From 48bc25613f91b69d9ee68e8211f8bf22317aa40a 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/25] 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>
(cherry picked from commit 5315f988d9f175e4850f4259f691a68d95ce7ac2)
---
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 e09d00108..0d6b9ac9f 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 ALL_ROTATIONS (RR_Rotate_0 | \
RR_Rotate_90 | \
@@ -391,6 +392,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)
@@ -405,6 +480,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 9175396f7..32442d88e 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -679,6 +679,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)
{
@@ -844,6 +865,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 36c4c4c8b..1317ae5bb 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -420,6 +420,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);
@@ -458,6 +459,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.28.0

View File

@ -1,137 +0,0 @@
From 12a0f852e3276cb5c60e44b8b0d6ddd97975fd42 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Mon, 27 Jan 2020 11:08:00 +0100
Subject: [PATCH xserver 14/25] xwayland: Cache client-id for the
window-manager client
Instead of iterating over all clients which are listening for events on the
root window and checking if the client we are dealing with is the one
listening for SubstructureRedirectMask | ResizeRedirectMask events and thus
is the window-manager, cache the client-id of the window-manager in
xwl_screen and use that when checking if a client is the window-manager.
Note that we cache and compare the client-id rather then the ClienPtr,
this saves reading the ClientPtr from the global clients array when doing
the comparison.
Suggested-by: Olivier Fourdan <ofourdan@redhat.com>
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit ded89300c1dd541f59fe6e93c5c69d7fe7088244)
---
hw/xwayland/xwayland.c | 48 ++++++++++++++++++++++++++++--------------
hw/xwayland/xwayland.h | 2 ++
2 files changed, 34 insertions(+), 16 deletions(-)
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 32442d88e..f99cdf81f 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -565,20 +565,11 @@ xwl_window_enable_viewport(struct xwl_window *xwl_window,
}
static Bool
-xwl_screen_client_is_window_manager(struct xwl_screen *xwl_screen,
- ClientPtr client)
+window_is_wm_window(WindowPtr window)
{
- 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;
- }
- }
+ struct xwl_screen *xwl_screen = xwl_screen_get(window->drawable.pScreen);
- return FALSE;
+ return CLIENT_ID(window->drawable.id) == xwl_screen->wm_client_id;
}
static ClientPtr
@@ -592,7 +583,7 @@ xwl_window_get_owner(struct xwl_window *xwl_window)
* 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_is_wm_window(window)) {
if (window->firstChild && window->firstChild == window->lastChild)
return wClient(window->firstChild);
else
@@ -687,9 +678,7 @@ xwl_screen_check_resolution_change_emulation(struct xwl_screen *xwl_screen)
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)))
+ if (window_is_wm_window(window))
return FALSE;
/* CSD and override-redirect toplevel windows */
@@ -964,6 +953,30 @@ xwl_set_window_pixmap(WindowPtr window,
ensure_surface_for_window(window);
}
+static Bool
+xwl_change_window_attributes(WindowPtr window, unsigned long mask)
+{
+ ScreenPtr screen = window->drawable.pScreen;
+ struct xwl_screen *xwl_screen = xwl_screen_get(screen);
+ OtherClients *others;
+ Bool ret;
+
+ screen->ChangeWindowAttributes = xwl_screen->ChangeWindowAttributes;
+ ret = (*screen->ChangeWindowAttributes) (window, mask);
+ xwl_screen->ChangeWindowAttributes = screen->ChangeWindowAttributes;
+ screen->ChangeWindowAttributes = xwl_change_window_attributes;
+
+ if (window != screen->root || !(mask & CWEventMask))
+ return ret;
+
+ for (others = wOtherClients(window); others; others = others->next) {
+ if (others->mask & (SubstructureRedirectMask | ResizeRedirectMask))
+ xwl_screen->wm_client_id = CLIENT_ID(others->resource);
+ }
+
+ return ret;
+}
+
static void
xwl_resize_window(WindowPtr window,
int x, int y,
@@ -1568,6 +1581,9 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
xwl_screen->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = xwl_close_screen;
+ xwl_screen->ChangeWindowAttributes = pScreen->ChangeWindowAttributes;
+ pScreen->ChangeWindowAttributes = xwl_change_window_attributes;
+
xwl_screen->ResizeWindow = pScreen->ResizeWindow;
pScreen->ResizeWindow = xwl_resize_window;
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index 1317ae5bb..f5ffadfcc 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -118,6 +118,7 @@ struct xwl_screen {
int height;
int depth;
ScreenPtr screen;
+ int wm_client_id;
int expecting_event;
enum RootClipMode root_clip_mode;
@@ -135,6 +136,7 @@ struct xwl_screen {
DestroyWindowProcPtr DestroyWindow;
XYToWindowProcPtr XYToWindow;
SetWindowPixmapProcPtr SetWindowPixmap;
+ ChangeWindowAttributesProcPtr ChangeWindowAttributes;
ResizeWindowProcPtr ResizeWindow;
struct xorg_list output_list;
--
2.28.0

View File

@ -1,50 +0,0 @@
From 5448ffeb9b06d20e821174c04d2280933e3ca993 Mon Sep 17 00:00:00 2001
From: Roman Gilg <subdiff@gmail.com>
Date: Fri, 3 Jan 2020 17:12:14 +0100
Subject: [PATCH xserver 15/25] xwayland: Reuse viewport instead of recreating
When a viewport is already created we can reuse this object instead of
destroying it and getting a new one for updating the source rectangle and
destination size.
Signed-off-by: Roman Gilg <subdiff@gmail.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 948e02872feb641a176b3af82b6ef1201c97bb16)
---
hw/xwayland/xwayland.c | 18 +++++++-----------
1 file changed, 7 insertions(+), 11 deletions(-)
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index f99cdf81f..8de3dd36b 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -539,17 +539,13 @@ 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);
+ if (!xwl_window_has_viewport_enabled(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),
--
2.28.0

View File

@ -1,81 +0,0 @@
From 2896f732af4c74f124d767808a24005342d8f125 Mon Sep 17 00:00:00 2001
From: Roman Gilg <subdiff@gmail.com>
Date: Fri, 3 Jan 2020 17:27:28 +0100
Subject: [PATCH xserver 16/25] xwayland: Recurse on finding the none-wm owner
An X11 window manager might add a chain of parent windows when reparenting to a
decoration window.
That is for example the case for KWin, which reparents client windows to one
decoration and another wrapper parent window.
Account for that by a recursion into the tree. For now assume as before that
all X11 window managers reparent with one child only for these parent windows.
Changes by Hans de Goede:
- Move the xwl_window_is_toplevel() from a later patch in this series here
as it really belongs together with these changes
- Drop no longer necessary xwl_window argument from window_get_none_wm_owner
parameters
Signed-off-by: Roman Gilg <subdiff@gmail.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit a69f7fbb54efc8ffad320c8afd23cb41fc9edc27)
---
hw/xwayland/xwayland.c | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 8de3dd36b..c38c4180b 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -569,19 +569,18 @@ window_is_wm_window(WindowPtr window)
}
static ClientPtr
-xwl_window_get_owner(struct xwl_window *xwl_window)
+window_get_none_wm_owner(WindowPtr 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.
+ * actual client toplevel window has been reparented to some window-manager
+ * decoration/wrapper windows. In that case recurse by checking the client
+ * of the first *and only* child of the decoration/wrapper window.
*/
if (window_is_wm_window(window)) {
if (window->firstChild && window->firstChild == window->lastChild)
- return wClient(window->firstChild);
+ return window_get_none_wm_owner(window->firstChild);
else
return NULL; /* Should never happen, skip resolution emulation */
}
@@ -602,7 +601,7 @@ xwl_window_should_enable_viewport(struct xwl_window *xwl_window,
if (!xwl_screen_has_resolution_change_emulation(xwl_screen))
return FALSE;
- owner = xwl_window_get_owner(xwl_window);
+ owner = window_get_none_wm_owner(xwl_window->window);
if (!owner)
return FALSE;
@@ -681,8 +680,8 @@ xwl_window_is_toplevel(WindowPtr window)
if (window_get_damage(window))
return TRUE;
- /* Normal toplevel client windows, reparented to decoration window */
- return (window->parent && window_get_damage(window->parent));
+ /* Normal toplevel client windows, reparented to a window-manager window */
+ return window->parent && window_is_wm_window(window->parent);
}
static void
--
2.28.0

View File

@ -1,82 +0,0 @@
From dd83985179b4a3c2613c96922eafeea40e21b7d2 Mon Sep 17 00:00:00 2001
From: Roman Gilg <subdiff@gmail.com>
Date: Wed, 15 Jan 2020 10:07:58 +0100
Subject: [PATCH xserver 17/25] xwayland: Make window_get_none_wm_owner return
a Window instead of a Client
Make window_get_none_wm_owner return the first non-wm-window instead of the
owner (client) of the first non-wm-window and rename it to
window_get_client_toplevel to match its new behavior.
This is a preparation patch for switching to using the drawable coordinates
in xwl_window_should_enable_viewport()
Changes by Hans de Goede:
- Split this change out into a separate patch for easier reviewing
- Rename window_get_none_wm_owner to window_get_client_toplevel to match
its new behavior
Signed-off-by: Roman Gilg <subdiff@gmail.com>
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 060f10062eb1761515b762b46cba56c7a53db72c)
---
hw/xwayland/xwayland.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index c38c4180b..b3b80beae 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -568,10 +568,10 @@ window_is_wm_window(WindowPtr window)
return CLIENT_ID(window->drawable.id) == xwl_screen->wm_client_id;
}
-static ClientPtr
-window_get_none_wm_owner(WindowPtr window)
+static WindowPtr
+window_get_client_toplevel(WindowPtr window)
{
- ClientPtr client = wClient(window);
+ assert(window);
/* If the toplevel window is owned by the window-manager, then the
* actual client toplevel window has been reparented to some window-manager
@@ -580,12 +580,12 @@ window_get_none_wm_owner(WindowPtr window)
*/
if (window_is_wm_window(window)) {
if (window->firstChild && window->firstChild == window->lastChild)
- return window_get_none_wm_owner(window->firstChild);
+ return window_get_client_toplevel(window->firstChild);
else
return NULL; /* Should never happen, skip resolution emulation */
}
- return client;
+ return window;
}
static Bool
@@ -597,14 +597,17 @@ xwl_window_should_enable_viewport(struct xwl_window *xwl_window,
struct xwl_emulated_mode *emulated_mode;
struct xwl_output *xwl_output;
ClientPtr owner;
+ WindowPtr window;
if (!xwl_screen_has_resolution_change_emulation(xwl_screen))
return FALSE;
- owner = window_get_none_wm_owner(xwl_window->window);
- if (!owner)
+ window = window_get_client_toplevel(xwl_window->window);
+ if (!window)
return FALSE;
+ owner = wClient(window);
+
/* 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)
*/
--
2.28.0

View File

@ -1,121 +0,0 @@
From be8c65e84dc4bee97bd0115a89c037fb47053d4c Mon Sep 17 00:00:00 2001
From: Roman Gilg <subdiff@gmail.com>
Date: Fri, 3 Jan 2020 17:55:28 +0100
Subject: [PATCH xserver 18/25] xwayland: Check emulation on client toplevel
resize
When a reparented window is resized directly check the emulation instead of
doing this only when the window manager parent window is resized, what might
never happen.
For that to work we need to make sure that we compare the current size of the
client toplevel when looking for an emulated mode.
Changes by Hans de Goede:
- Remove xwl_window x, y, width and height members as those are no longer used.
- Add check for xwl_window_from_window() returning NULL.
Signed-off-by: Roman Gilg <subdiff@gmail.com>
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 6d98f840da6dfcf2a69e03a1b3fa0bf602ba1f27)
---
hw/xwayland/xwayland.c | 27 +++++++++++----------------
hw/xwayland/xwayland.h | 1 -
2 files changed, 11 insertions(+), 17 deletions(-)
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index b3b80beae..b2e46336c 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -598,6 +598,7 @@ xwl_window_should_enable_viewport(struct xwl_window *xwl_window,
struct xwl_output *xwl_output;
ClientPtr owner;
WindowPtr window;
+ DrawablePtr drawable;
if (!xwl_screen_has_resolution_change_emulation(xwl_screen))
return FALSE;
@@ -607,6 +608,7 @@ xwl_window_should_enable_viewport(struct xwl_window *xwl_window,
return FALSE;
owner = wClient(window);
+ drawable = &window->drawable;
/* 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)
@@ -616,10 +618,10 @@ xwl_window_should_enable_viewport(struct xwl_window *xwl_window,
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) {
+ if (drawable->x == xwl_output->x &&
+ drawable->y == xwl_output->y &&
+ drawable->width == emulated_mode->width &&
+ drawable->height == emulated_mode->height) {
*emulated_mode_ret = emulated_mode;
*xwl_output_ret = xwl_output;
@@ -635,9 +637,9 @@ xwl_window_should_enable_viewport(struct xwl_window *xwl_window,
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) {
+ drawable->x == 0 && drawable->y == 0 &&
+ drawable->width == xwl_screen->width &&
+ drawable->height == xwl_screen->height) {
*emulated_mode_ret = emulated_mode;
*xwl_output_ret = xwl_output;
@@ -757,8 +759,6 @@ 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");
@@ -986,20 +986,15 @@ xwl_resize_window(WindowPtr window,
struct xwl_window *xwl_window;
xwl_screen = xwl_screen_get(screen);
- xwl_window = xwl_window_get(window);
+ xwl_window = xwl_window_from_window(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;
+ if (xwl_window && xwl_window_is_toplevel(window))
xwl_window_check_resolution_change_emulation(xwl_window);
- }
}
static void
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index f5ffadfcc..0d0baac9b 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -184,7 +184,6 @@ 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;
--
2.28.0

View File

@ -1,45 +0,0 @@
From 555e00dbf71d7c5b792bacd789cdde9c42203ff1 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Wed, 15 Jan 2020 14:36:45 +0100
Subject: [PATCH xserver 19/25] xwayland: Also check
resolution-change-emulation when the xwl_window itself moves
The recent change to use the top-level non-window-manager Window drawable
coordinates from xwl_window_check_resolution_change_emulation() in
combination with only calling it on a resize when the top-level window
is moved breaks things with mutter/gnome-shell.
When fullscreening a X11 window, mutter moves its window-decoration Window
wrapping the top-level Window to the monitor's origin coordinates (e.g. 0x0)
last. This updates the top-level's drawable coordinates, but as the
actual MoveWindow is called on the wrapper Window and not on the toplevel
we do not call xwl_window_check_resolution_change_emulation() and we never
enable the viewport.
This commit fixes this by also calling
xwl_window_check_resolution_change_emulation() if the Window being moved
is an xwl_window itself.
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 4fc107460a349a1a46f0e5251e6fd2a31f4c0428)
---
hw/xwayland/xwayland.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index b2e46336c..e07dabcfa 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -993,7 +993,7 @@ xwl_resize_window(WindowPtr window,
xwl_screen->ResizeWindow = screen->ResizeWindow;
screen->ResizeWindow = xwl_resize_window;
- if (xwl_window && xwl_window_is_toplevel(window))
+ if (xwl_window && (xwl_window_get(window) || xwl_window_is_toplevel(window)))
xwl_window_check_resolution_change_emulation(xwl_window);
}
--
2.28.0

View File

@ -1,83 +0,0 @@
From 46ccf740dc5e81d84b2e8c19f6211eaf1d8d06de Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 9 Jan 2020 11:00:36 +0100
Subject: [PATCH xserver 20/25] xwayland: Also hook screen's MoveWindow method
Not only hook the ResizeWindow method of the screen (which really is
MoveAndResize) but also hook the MoveWindow method for checking if we
need to setup a viewport for resolution change emulation.
Our resolution change emulation check if the windows origin matches
the monitors origin and the windows origin can also be changed by just
a move without being resized.
Also checking on a move becomes esp. important when we move to checking
on changes to the top-level non-window-manager client (X11)Window instead
of on changes to the xwl_window later on in this patch series.
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 10df0437a2b142e61c4d84ffffa9592ac6846ef1)
---
hw/xwayland/xwayland.c | 25 +++++++++++++++++++++++++
hw/xwayland/xwayland.h | 1 +
2 files changed, 26 insertions(+)
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index e07dabcfa..4f19f3710 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -997,6 +997,28 @@ xwl_resize_window(WindowPtr window,
xwl_window_check_resolution_change_emulation(xwl_window);
}
+static void
+xwl_move_window(WindowPtr window,
+ int x, int y,
+ WindowPtr next_sib,
+ VTKind kind)
+{
+ 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_from_window(window);
+
+ screen->MoveWindow = xwl_screen->MoveWindow;
+ (*screen->MoveWindow) (window, x, y, next_sib, kind);
+ xwl_screen->MoveWindow = screen->MoveWindow;
+ screen->MoveWindow = xwl_move_window;
+
+ if (xwl_window && (xwl_window_get(window) || xwl_window_is_toplevel(window)))
+ xwl_window_check_resolution_change_emulation(xwl_window);
+}
+
static void
frame_callback(void *data,
struct wl_callback *callback,
@@ -1580,6 +1602,9 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
xwl_screen->ResizeWindow = pScreen->ResizeWindow;
pScreen->ResizeWindow = xwl_resize_window;
+ xwl_screen->MoveWindow = pScreen->MoveWindow;
+ pScreen->MoveWindow = xwl_move_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 0d0baac9b..451c08e23 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -138,6 +138,7 @@ struct xwl_screen {
SetWindowPixmapProcPtr SetWindowPixmap;
ChangeWindowAttributesProcPtr ChangeWindowAttributes;
ResizeWindowProcPtr ResizeWindow;
+ MoveWindowProcPtr MoveWindow;
struct xorg_list output_list;
struct xorg_list seat_list;
--
2.28.0

View File

@ -1,63 +0,0 @@
From d64f12d119e4abe3ef337741bf7b38f8de2f9da9 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 21/25] 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.
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 88342353de45e64f408c38bb10cd1506ba0f159a)
---
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 0d6b9ac9f..4bc9cd6b8 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -272,8 +272,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 */
@@ -474,7 +477,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.28.0

View File

@ -1,48 +0,0 @@
From 677fd1ade4547008b0d67eec460770e002595c3c 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 22/25] 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.
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 4cfc2677f5c82ca5db0919de549b9b077f1ba113)
---
hw/xwayland/xwayland.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 4f19f3710..5bb7a68e9 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -808,6 +808,11 @@ ensure_surface_for_window(WindowPtr window)
xwl_window_init_allow_commits(xwl_window);
+ if (!window_is_wm_window(window)) {
+ /* CSD or O-R toplevel window, check viewport on creation */
+ xwl_window_check_resolution_change_emulation(xwl_window);
+ }
+
return TRUE;
err_surf:
--
2.28.0

View File

@ -1,76 +0,0 @@
From 049333a0ecf8574a0612bf27850f9682f0f70533 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 23/25] 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.
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 148f428dfccf606b932a00d5a00af06e8dca8a7e)
---
hw/xwayland/xwayland.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 5bb7a68e9..1600c00cd 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -738,6 +738,7 @@ ensure_surface_for_window(WindowPtr window)
struct xwl_screen *xwl_screen;
struct xwl_window *xwl_window;
struct wl_region *region;
+ WindowPtr toplevel;
if (xwl_window_from_window(window))
return TRUE;
@@ -808,7 +809,14 @@ ensure_surface_for_window(WindowPtr window)
xwl_window_init_allow_commits(xwl_window);
- if (!window_is_wm_window(window)) {
+ /* When a new window-manager window is realized, then the randr emulation
+ * props may have not been set on the managed client window yet.
+ */
+ if (window_is_wm_window(window)) {
+ toplevel = window_get_client_toplevel(window);
+ if (toplevel)
+ xwl_output_set_window_randr_emu_props(xwl_screen, toplevel);
+ } else {
/* CSD or O-R toplevel window, check viewport on creation */
xwl_window_check_resolution_change_emulation(xwl_window);
}
@@ -857,8 +865,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.28.0

View File

@ -1,49 +0,0 @@
From f1d77ed7ac9ee9bc2f0cf60b0e4604bae092ebd0 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 24/25] 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.
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit d4faab8708779df265239b203ed5f020bff681bf)
---
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 4bc9cd6b8..9d3372c8e 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -431,9 +431,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,
@@ -446,7 +443,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.28.0

View File

@ -1,37 +0,0 @@
From b5c62ae463101712a2ed91e976b28af5d1e73064 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <mdaenzer@redhat.com>
Date: Fri, 6 Nov 2020 10:14:19 +0100
Subject: [PATCH xserver 25/25] xwayland: Make window_get_client_toplevel
non-recursive
Noticed while reading the code.
Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
(cherry picked from commit df3aa4922fd7e256169e541188b724f67ca948e1)
---
hw/xwayland/xwayland.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 1600c00cd..a5756ea14 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -578,11 +578,11 @@ window_get_client_toplevel(WindowPtr window)
* decoration/wrapper windows. In that case recurse by checking the client
* of the first *and only* child of the decoration/wrapper window.
*/
- if (window_is_wm_window(window)) {
- if (window->firstChild && window->firstChild == window->lastChild)
- return window_get_client_toplevel(window->firstChild);
- else
+ while (window_is_wm_window(window)) {
+ if (!window->firstChild || window->firstChild != window->lastChild)
return NULL; /* Should never happen, skip resolution emulation */
+
+ window = window->firstChild;
}
return window;
--
2.28.0

View File

@ -46,7 +46,7 @@
Summary: X.Org X11 X server
Name: xorg-x11-server
Version: 1.20.10
Release: 2%{?gitdate:.%{gitdate}}%{?dist}
Release: 4%{?gitdate:.%{gitdate}}%{?dist}
URL: http://www.x.org
License: MIT
@ -98,33 +98,6 @@ Patch6: 0001-Fedora-hack-Make-the-suid-root-wrapper-always-start-.patch
# Backports from "master" upstream:
# <empty>
# Backported Xwayland randr resolution change emulation support
Patch501: 0001-dix-Add-GetCurrentClient-helper.patch
Patch502: 0002-xwayland-Add-wp_viewport-wayland-extension-support.patch
Patch503: 0003-xwayland-Use-buffer_damage-instead-of-surface-damage.patch
Patch504: 0004-xwayland-Add-fake-output-modes-to-xrandr-output-mode.patch
Patch505: 0005-xwayland-Use-RandR-1.2-interface-rev-2.patch
Patch506: 0006-xwayland-Add-per-client-private-data.patch
Patch507: 0007-xwayland-Add-support-for-storing-per-client-per-outp.patch
Patch508: 0008-xwayland-Add-support-for-randr-resolution-change-emu.patch
Patch509: 0009-xwayland-Add-xwlRRModeToDisplayMode-helper-function.patch
Patch510: 0010-xwayland-Add-xwlVidModeGetCurrentRRMode-helper-to-th.patch
Patch511: 0011-xwayland-Add-vidmode-mode-changing-emulation-support.patch
Patch512: 0012-xwayland-xwl_window_should_enable_viewport-Add-extra.patch
Patch513: 0013-xwayland-Set-_XWAYLAND_RANDR_EMU_MONITOR_RECTS-prope.patch
Patch514: 0014-xwayland-Cache-client-id-for-the-window-manager-clie.patch
Patch515: 0015-xwayland-Reuse-viewport-instead-of-recreating.patch
Patch516: 0016-xwayland-Recurse-on-finding-the-none-wm-owner.patch
Patch517: 0017-xwayland-Make-window_get_none_wm_owner-return-a-Wind.patch
Patch518: 0018-xwayland-Check-emulation-on-client-toplevel-resize.patch
Patch519: 0019-xwayland-Also-check-resolution-change-emulation-when.patch
Patch520: 0020-xwayland-Also-hook-screen-s-MoveWindow-method.patch
Patch521: 0021-xwayland-Fix-emulated-modes-not-being-removed-when-s.patch
Patch522: 0022-xwayland-Call-xwl_window_check_resolution_change_emu.patch
Patch523: 0023-xwayland-Fix-setting-of-_XWAYLAND_RANDR_EMU_MONITOR_.patch
Patch524: 0024-xwayland-Remove-unnecessary-xwl_window_is_toplevel-c.patch
Patch525: 0025-xwayland-Make-window_get_client_toplevel-non-recursi.patch
BuildRequires: make
BuildRequires: systemtap-sdt-devel
BuildRequires: git-core
@ -145,10 +118,6 @@ BuildRequires: libXinerama-devel libXi-devel
BuildRequires: libXt-devel libdmx-devel libXmu-devel libXrender-devel
BuildRequires: libXi-devel libXpm-devel libXaw-devel libXfixes-devel
BuildRequires: wayland-devel
BuildRequires: wayland-protocols-devel
BuildRequires: pkgconfig(wayland-eglstream-protocols)
BuildRequires: pkgconfig(wayland-client) >= 1.3.0
BuildRequires: pkgconfig(epoxy)
BuildRequires: pkgconfig(xshmfence) >= 1.1
BuildRequires: libXv-devel
@ -285,15 +254,6 @@ X protocol, and therefore supports the newer X extensions like
Render and Composite.
%package Xwayland
Summary: Wayland X Server
Requires: xorg-x11-server-common >= %{version}-%{release}
Requires: libEGL
%description Xwayland
Xwayland is an X server for running X clients under Wayland.
%package devel
Summary: SDK for X server driver module development
Requires: xorg-x11-util-macros
@ -376,7 +336,6 @@ autoreconf -f -v --install || exit 1
%configure %{xservers} \
--enable-dependency-tracking \
--enable-xwayland-eglstream \
--disable-static \
--with-pic \
%{?no_int10} \
@ -392,7 +351,7 @@ autoreconf -f -v --install || exit 1
--enable-config-udev \
--disable-unit-tests \
--enable-dmx \
--enable-xwayland \
--disable-xwayland \
%{dri_flags} \
${CONFIGURE}
@ -539,9 +498,6 @@ find %{inst_srcdir}/hw/xfree86 -name \*.c -delete
%{_bindir}/Xephyr
%{_mandir}/man1/Xephyr.1*
%files Xwayland
%{_bindir}/Xwayland
%files devel
%doc COPYING
#{_docdir}/xorg-server
@ -556,6 +512,12 @@ find %{inst_srcdir}/hw/xfree86 -name \*.c -delete
%changelog
* Mon Feb 1 2021 Olivier Fourdan <ofourdan@redhat.com> - 1.20.10-4
- Remove Xwayland from the xserver builds
* Thu Jan 28 2021 Fedora Release Engineering <releng@fedoraproject.org> - 1.20.10-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Tue Jan 19 2021 Adam Jackson <ajax@redhat.com> - 1.20.10-2
- Disable int10 and vbe on RHEL
- Disable DRI1