<div dir="ltr"><div><div><div><div><div><div><div><div>Hi,<br><br></div>xdg-support has now been added to mutter (in git master), can we consider this patch (only this one for now) which adds xdg-output support to Xwayland?<br><br></div>Because of the difference between compositors, we cannot all patches at once, that would break either weston or mutter/gnome-shell.<br><br></div>So we need to proceed as follow:<br><br></div> 1. Land xdg-output support in mutter ← we're here</div><div> <a href="https://bugzilla.gnome.org/attachment.cgi?id=365582">https://bugzilla.gnome.org/attachment.cgi?id=365582</a><br></div> 2. Land xdg-output support in wayland</div><div> <a href="https://patchwork.freedesktop.org/patch/175575/">https://patchwork.freedesktop.org/patch/175575/</a><br><br></div>Then, once we have a release of both Xwayland and mutter supporting xdg-output:<br><br></div> 3. Land the patc hto send the correct output size and position in mutter<br> <a href="https://bugzilla.gnome.org/attachment.cgi?id=365575">https://bugzilla.gnome.org/attachment.cgi?id=365575</a><br></div> 4. Land the second patch of this series, to apply output scale to monitor resolution<br> <a href="https://patchwork.freedesktop.org/patch/175578/">https://patchwork.freedesktop.org/patch/175578/</a><br> <br><div><div><div><div><div><div>This way, in both weston and mutter/gnome-shell, a mode X×Y at scale 2 will still show up as X×Y in xrandr.</div><div><br></div><div>Cheers,</div><div>Olivier</div><div><br></div></div></div></div></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Sep 7, 2017 at 5:43 PM, Olivier Fourdan <span dir="ltr"><<a href="mailto:ofourdan@redhat.com" target="_blank">ofourdan@redhat.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">The xdg-output protocol aims at describing outputs in way which is<br>
more in line with the concept of an output on desktop oriented systems.<br>
<br>
For now it just features the position and logical size which describe<br>
the output position and size in the global compositor space.<br>
<br>
This is however much useful for Xwayland to advertise the output size<br>
and position to X11 clients which need this to configure their surfaces<br>
in the global compositor space as the compositor may apply a different<br>
scale from what is advertised by the output scaling property (to achieve<br>
fractional scaling, for example).<br>
<br>
This was added in wayland-protocols 1.10.<br>
<br>
Signed-off-by: Olivier Fourdan <<a href="mailto:ofourdan@redhat.com">ofourdan@redhat.com</a>><br>
---<br>
<a href="http://configure.ac" rel="noreferrer" target="_blank">configure.ac</a> | 2 +-<br>
hw/xwayland/Makefile.am | 9 +++-<br>
hw/xwayland/meson.build | 2 +<br>
hw/xwayland/xwayland-output.c | 119 ++++++++++++++++++++++++++++++<wbr>++++++++----<br>
hw/xwayland/xwayland.c | 5 ++<br>
hw/xwayland/xwayland.h | 8 +++<br>
meson.build | 2 +-<br>
7 files changed, 134 insertions(+), 13 deletions(-)<br>
<br>
diff --git a/<a href="http://configure.ac" rel="noreferrer" target="_blank">configure.ac</a> b/<a href="http://configure.ac" rel="noreferrer" target="_blank">configure.ac</a><br>
index eee1257a9..3f4206727 100644<br>
--- a/<a href="http://configure.ac" rel="noreferrer" target="_blank">configure.ac</a><br>
+++ b/<a href="http://configure.ac" rel="noreferrer" target="_blank">configure.ac</a><br>
@@ -2350,7 +2350,7 @@ AM_CONDITIONAL(XEPHYR, [test "x$KDRIVE" = xyes && test "x$XEPHYR" = xyes])<br>
<br>
dnl Xwayland DDX<br>
<br>
-XWAYLANDMODULES="wayland-<wbr>client >= 1.3.0 wayland-protocols >= 1.9 $LIBDRM epoxy"<br>
+XWAYLANDMODULES="wayland-<wbr>client >= 1.3.0 wayland-protocols >= 1.10 $LIBDRM epoxy"<br>
if test "x$XF86VIDMODE" = xyes; then<br>
XWAYLANDMODULES="$<wbr>XWAYLANDMODULES $VIDMODEPROTO"<br>
fi<br>
diff --git a/hw/xwayland/Makefile.am b/hw/xwayland/Makefile.am<br>
index eda49799e..7204591e3 100644<br>
--- a/hw/xwayland/Makefile.am<br>
+++ b/hw/xwayland/Makefile.am<br>
@@ -59,7 +59,10 @@ Xwayland_built_sources += \<br>
tablet-unstable-v2-client-<wbr>protocol.h \<br>
tablet-unstable-v2-protocol.c \<br>
xwayland-keyboard-grab-<wbr>unstable-v1-protocol.c \<br>
- xwayland-keyboard-grab-<wbr>unstable-v1-client-protocol.h<br>
+ xwayland-keyboard-grab-<wbr>unstable-v1-client-protocol.h \<br>
+ xdg-output-unstable-v1-<wbr>protocol.c \<br>
+ xdg-output-unstable-v1-client-<wbr>protocol.h<br>
+<br>
<br>
nodist_Xwayland_SOURCES = $(Xwayland_built_sources)<br>
CLEANFILES = $(Xwayland_built_sources)<br>
@@ -91,6 +94,10 @@ xwayland-keyboard-grab-<wbr>unstable-v1-protocol.c : $(WAYLAND_PROTOCOLS_DATADIR)/<wbr>uns<br>
$(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@<br>
xwayland-keyboard-grab-<wbr>unstable-v1-client-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)/<wbr>unstable/xwayland-keyboard-<wbr>grab/xwayland-keyboard-grab-<wbr>unstable-v1.xml<br>
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@<br>
+xdg-output-unstable-v1-<wbr>protocol.c : $(WAYLAND_PROTOCOLS_DATADIR)/<wbr>unstable/xdg-output/xdg-<wbr>output-unstable-v1.xml<br>
+ $(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@<br>
+xdg-output-unstable-v1-<wbr>client-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)/<wbr>unstable/xdg-output/xdg-<wbr>output-unstable-v1.xml<br>
+ $(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@<br>
<br>
%-protocol.c : %.xml<br>
$(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@<br>
diff --git a/hw/xwayland/meson.build b/hw/xwayland/meson.build<br>
index b619a66a7..658483aca 100644<br>
--- a/hw/xwayland/meson.build<br>
+++ b/hw/xwayland/meson.build<br>
@@ -19,6 +19,7 @@ pointer_xml = join_paths(protodir, 'unstable', 'pointer-constraints', 'pointer-c<br>
relative_xml = join_paths(protodir, 'unstable', 'relative-pointer', 'relative-pointer-unstable-v1.<wbr>xml')<br>
tablet_xml = join_paths(protodir, 'unstable', 'tablet', 'tablet-unstable-v2.xml')<br>
kbgrab_xml = join_paths(protodir, 'unstable', 'xwayland-keyboard-grab', 'xwayland-keyboard-grab-<wbr>unstable-v1.xml')<br>
+xdg_output_xml = join_paths(protodir, 'unstable', 'xdg-output', 'xdg-output-unstable-v1.xml')<br>
<br>
client_header = generator(scanner,<br>
output : '@BASENAME@-client-protocol.h'<wbr>,<br>
@@ -36,6 +37,7 @@ srcs += code.process(relative_xml)<br>
srcs += code.process(pointer_xml)<br>
srcs += code.process(tablet_xml)<br>
srcs += code.process(kbgrab_xml)<br>
+srcs += code.process(xdg_output_xml)<br>
<br>
xwayland_glamor = []<br>
if gbm_dep.found()<br>
diff --git a/hw/xwayland/xwayland-output.<wbr>c b/hw/xwayland/xwayland-output.<wbr>c<br>
index 460caaf56..a504d2595 100644<br>
--- a/hw/xwayland/xwayland-output.<wbr>c<br>
+++ b/hw/xwayland/xwayland-output.<wbr>c<br>
@@ -93,9 +93,12 @@ output_handle_geometry(void *data, struct wl_output *wl_output, int x, int y,<br>
physical_width, physical_height);<br>
RROutputSetSubpixelOrder(xwl_<wbr>output->randr_output,<br>
wl_subpixel_to_xrandr(<wbr>subpixel));<br>
- xwl_output->x = x;<br>
- xwl_output->y = y;<br>
<br>
+ /* Apply the change from wl_output only if xdg-output is not supported */<br>
+ if (!xwl_output->xdg_output) {<br>
+ xwl_output->x = x;<br>
+ xwl_output->y = y;<br>
+ }<br>
xwl_output->rotation = wl_transform_to_xrandr(<wbr>transform);<br>
}<br>
<br>
@@ -108,18 +111,22 @@ output_handle_mode(void *data, struct wl_output *wl_output, uint32_t flags,<br>
if (!(flags & WL_OUTPUT_MODE_CURRENT))<br>
return;<br>
<br>
- xwl_output->width = width;<br>
- xwl_output->height = height;<br>
+ /* Apply the change from wl_output only if xdg-output is not supported */<br>
+ if (!xwl_output->xdg_output) {<br>
+ xwl_output->width = width;<br>
+ xwl_output->height = height;<br>
+ }<br>
xwl_output->refresh = refresh;<br>
}<br>
<br>
static inline void<br>
output_get_new_size(struct xwl_output *xwl_output,<br>
+ Bool need_rotate,<br>
int *height, int *width)<br>
{<br>
int output_width, output_height;<br>
<br>
- if (xwl_output->rotation & (RR_Rotate_0 | RR_Rotate_180)) {<br>
+ if (need_rotate && (xwl_output->rotation & (RR_Rotate_0 | RR_Rotate_180))) {<br>
output_width = xwl_output->width;<br>
output_height = xwl_output->height;<br>
} else {<br>
@@ -200,12 +207,20 @@ update_screen_size(struct xwl_output *xwl_output, int width, int height)<br>
}<br>
<br>
static void<br>
-output_handle_done(void *data, struct wl_output *wl_output)<br>
+apply_output_change(struct xwl_output *xwl_output)<br>
{<br>
- struct xwl_output *it, *xwl_output = data;<br>
struct xwl_screen *xwl_screen = xwl_output->xwl_screen;<br>
+ struct xwl_output *it;<br>
int width = 0, height = 0, has_this_output = 0;<br>
RRModePtr randr_mode;<br>
+ Bool need_rotate;<br>
+<br>
+ /* Clear out the "done" received flags */<br>
+ xwl_output->wl_output_done = FALSE;<br>
+ xwl_output->xdg_output_done = FALSE;<br>
+<br>
+ /* xdg-output sends output size in compositor space. so alredy rotated */<br>
+ need_rotate = (xwl_output->xdg_output != NULL);<br>
<br>
randr_mode = xwayland_cvt(xwl_output-><wbr>width, xwl_output->height,<br>
xwl_output->refresh / 1000.0, 0, 0);<br>
@@ -222,14 +237,14 @@ output_handle_done(void *data, struct wl_output *wl_output)<br>
if (it == xwl_output)<br>
has_this_output = 1;<br>
<br>
- output_get_new_size(it, &height, &width);<br>
+ output_get_new_size(it, need_rotate, &height, &width);<br>
}<br>
<br>
if (!has_this_output) {<br>
xorg_list_append(&xwl_output-><wbr>link, &xwl_screen->output_list);<br>
<br>
/* we did not check this output for new screen size, do it now */<br>
- output_get_new_size(xwl_<wbr>output, &height, &width);<br>
+ output_get_new_size(xwl_<wbr>output, need_rotate, &height, &width);<br>
<br>
--xwl_screen->expecting_event;<br>
}<br>
@@ -238,6 +253,19 @@ output_handle_done(void *data, struct wl_output *wl_output)<br>
}<br>
<br>
static void<br>
+output_handle_done(void *data, struct wl_output *wl_output)<br>
+{<br>
+ struct xwl_output *xwl_output = data;<br>
+<br>
+ xwl_output->wl_output_done = TRUE;<br>
+ /* Apply the changes from wl_output only if both "done" events are reveived,<br>
+ * or if xdg-output is not supported.<br>
+ */<br>
+ if (xwl_output->xdg_output_done || !xwl_output->xdg_output)<br>
+ apply_output_change(xwl_<wbr>output);<br>
+}<br>
+<br>
+static void<br>
output_handle_scale(void *data, struct wl_output *wl_output, int32_t factor)<br>
{<br>
}<br>
@@ -249,6 +277,42 @@ static const struct wl_output_listener output_listener = {<br>
output_handle_scale<br>
};<br>
<br>
+static void<br>
+xdg_output_handle_logical_<wbr>position(void *data, struct zxdg_output_v1 *xdg_output,<br>
+ int32_t x, int32_t y)<br>
+{<br>
+ struct xwl_output *xwl_output = data;<br>
+<br>
+ xwl_output->x = x;<br>
+ xwl_output->y = y;<br>
+}<br>
+<br>
+static void<br>
+xdg_output_handle_logical_<wbr>size(void *data, struct zxdg_output_v1 *xdg_output,<br>
+ int32_t width, int32_t height)<br>
+{<br>
+ struct xwl_output *xwl_output = data;<br>
+<br>
+ xwl_output->width = width;<br>
+ xwl_output->height = height;<br>
+}<br>
+<br>
+static void<br>
+xdg_output_handle_done(void *data, struct zxdg_output_v1 *xdg_output)<br>
+{<br>
+ struct xwl_output *xwl_output = data;<br>
+<br>
+ xwl_output->xdg_output_done = TRUE;<br>
+ if (xwl_output->wl_output_done)<br>
+ apply_output_change(xwl_<wbr>output);<br>
+}<br>
+<br>
+static const struct zxdg_output_v1_listener xdg_output_listener = {<br>
+ xdg_output_handle_logical_<wbr>position,<br>
+ xdg_output_handle_logical_<wbr>size,<br>
+ xdg_output_handle_done,<br>
+};<br>
+<br>
struct xwl_output *<br>
xwl_output_create(struct xwl_screen *xwl_screen, uint32_t id)<br>
{<br>
@@ -293,6 +357,15 @@ xwl_output_create(struct xwl_screen *xwl_screen, uint32_t id)<br>
RROutputSetCrtcs(xwl_output-><wbr>randr_output, &xwl_output->randr_crtc, 1);<br>
RROutputSetConnection(xwl_<wbr>output->randr_output, RR_Connected);<br>
<br>
+ /* We want the output to be in the list as soon as created so we can<br>
+ * use it when binding to the xdg-output protocol...<br>
+ */<br>
+ xorg_list_append(&xwl_output-><wbr>link, &xwl_screen->output_list);<br>
+ --xwl_screen->expecting_event;<br>
+<br>
+ if (xwl_screen->xdg_output_<wbr>manager)<br>
+ xwl_output_get_xdg_output(xwl_<wbr>output);<br>
+<br>
return xwl_output;<br>
<br>
err:<br>
@@ -317,13 +390,14 @@ xwl_output_remove(struct xwl_output *xwl_output)<br>
struct xwl_output *it;<br>
struct xwl_screen *xwl_screen = xwl_output->xwl_screen;<br>
int width = 0, height = 0;<br>
+ Bool need_rotate = (xwl_output->xdg_output != NULL);<br>
<br>
RRCrtcDestroy(xwl_output-><wbr>randr_crtc);<br>
RROutputDestroy(xwl_output-><wbr>randr_output);<br>
xorg_list_del(&xwl_output-><wbr>link);<br>
<br>
xorg_list_for_each_entry(it, &xwl_screen->output_list, link)<br>
- output_get_new_size(it, &height, &width);<br>
+ output_get_new_size(it, need_rotate, &height, &width);<br>
update_screen_size(xwl_output, width, height);<br>
<br>
xwl_output_destroy(xwl_output)<wbr>;<br>
@@ -360,3 +434,28 @@ xwl_screen_init_output(struct xwl_screen *xwl_screen)<br>
<br>
return TRUE;<br>
}<br>
+<br>
+void<br>
+xwl_output_get_xdg_output(<wbr>struct xwl_output *xwl_output)<br>
+{<br>
+ struct xwl_screen *xwl_screen = xwl_output->xwl_screen;<br>
+<br>
+ xwl_output->xdg_output =<br>
+ zxdg_output_manager_v1_get_<wbr>xdg_output (xwl_screen->xdg_output_<wbr>manager,<br>
+ xwl_output->output);<br>
+<br>
+ zxdg_output_v1_add_listener(<wbr>xwl_output->xdg_output,<br>
+ &xdg_output_listener,<br>
+ xwl_output);<br>
+}<br>
+<br>
+void<br>
+xwl_screen_init_xdg_output(<wbr>struct xwl_screen *xwl_screen)<br>
+{<br>
+ struct xwl_output *it;<br>
+<br>
+ assert(xwl_screen->xdg_output_<wbr>manager);<br>
+<br>
+ xorg_list_for_each_entry(it, &xwl_screen->output_list, link)<br>
+ xwl_output_get_xdg_output(it);<br>
+}<br>
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c<br>
index cb929cad5..3b6abde64 100644<br>
--- a/hw/xwayland/xwayland.c<br>
+++ b/hw/xwayland/xwayland.c<br>
@@ -675,6 +675,11 @@ registry_global(void *data, struct wl_registry *registry, uint32_t id,<br>
if (xwl_output_create(xwl_screen, id))<br>
xwl_screen->expecting_event++;<br>
}<br>
+ else if (strcmp(interface, "zxdg_output_manager_v1") == 0) {<br>
+ xwl_screen->xdg_output_manager =<br>
+ wl_registry_bind(registry, id, &zxdg_output_manager_v1_<wbr>interface, 1);<br>
+ xwl_screen_init_xdg_output(<wbr>xwl_screen);<br>
+ }<br>
#ifdef GLAMOR_HAS_GBM<br>
else if (xwl_screen->glamor &&<br>
strcmp(interface, "wl_drm") == 0 && version >= 2) {<br>
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h<br>
index 6d3edf33b..510d65e3c 100644<br>
--- a/hw/xwayland/xwayland.h<br>
+++ b/hw/xwayland/xwayland.h<br>
@@ -46,6 +46,7 @@<br>
#include "pointer-constraints-unstable-<wbr>v1-client-protocol.h"<br>
#include "tablet-unstable-v2-client-<wbr>protocol.h"<br>
#include "xwayland-keyboard-grab-<wbr>unstable-v1-client-protocol.h"<br>
+#include "xdg-output-unstable-v1-<wbr>client-protocol.h"<br>
<br>
struct xwl_screen {<br>
int width;<br>
@@ -82,6 +83,7 @@ struct xwl_screen {<br>
struct zwp_relative_pointer_manager_<wbr>v1 *relative_pointer_manager;<br>
struct zwp_pointer_constraints_v1 *pointer_constraints;<br>
struct zwp_xwayland_keyboard_grab_<wbr>manager_v1 *wp_grab;<br>
+ struct zxdg_output_manager_v1 *xdg_output_manager;<br>
uint32_t serial;<br>
<br>
#define XWL_FORMAT_ARGB8888 (1 << 0)<br>
@@ -258,12 +260,15 @@ struct xwl_tablet_pad {<br>
struct xwl_output {<br>
struct xorg_list link;<br>
struct wl_output *output;<br>
+ struct zxdg_output_v1 *xdg_output;<br>
uint32_t server_output_id;<br>
struct xwl_screen *xwl_screen;<br>
RROutputPtr randr_output;<br>
RRCrtcPtr randr_crtc;<br>
int32_t x, y, width, height, refresh;<br>
Rotation rotation;<br>
+ Bool wl_output_done;<br>
+ Bool xdg_output_done;<br>
};<br>
<br>
struct xwl_pixmap;<br>
@@ -326,6 +331,9 @@ struct wl_buffer *xwl_glamor_pixmap_get_wl_<wbr>buffer(PixmapPtr pixmap);<br>
<br>
void xwl_screen_release_tablet_<wbr>manager(struct xwl_screen *xwl_screen);<br>
<br>
+void xwl_output_get_xdg_output(<wbr>struct xwl_output *xwl_output);<br>
+void xwl_screen_init_xdg_output(<wbr>struct xwl_screen *xwl_screen);<br>
+<br>
#ifdef XV<br>
/* glamor Xv Adaptor */<br>
Bool xwl_glamor_xv_init(ScreenPtr pScreen);<br>
diff --git a/meson.build b/meson.build<br>
index 3efec0def..88fbdae0a 100644<br>
--- a/meson.build<br>
+++ b/meson.build<br>
@@ -98,7 +98,7 @@ if (host_machine.system() != 'darwin' and<br>
<br>
xwayland_dep = [<br>
dependency('wayland-client', version: '>= 1.3.0', required: xwayland_required),<br>
- dependency('wayland-protocols'<wbr>, version: '>= 1.9', required: xwayland_required),<br>
+ dependency('wayland-protocols'<wbr>, version: '>= 1.10', required: xwayland_required),<br>
dependency('libdrm', version: '>= 2.3.1', required: xwayland_required),<br>
dependency('epoxy', required: xwayland_required),<br>
]<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.13.5<br>
<br>
</font></span></blockquote></div><br></div>