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