From: Alexandros Frantzis alexandros.frantzis@collabora.com
Use the xdg-output-unstable-v1 protocol to get a unique, cross-process consistent name for the outputs.
Signed-off-by: Alexandros Frantzis alexandros.frantzis@collabora.com --- configure | 69 +++++++++++++++- configure.ac | 17 +++- dlls/winewayland.drv/Makefile.in | 3 + dlls/winewayland.drv/wayland.c | 12 +++ dlls/winewayland.drv/wayland_output.c | 111 +++++++++++++++++++++++--- dlls/winewayland.drv/waylanddrv.h | 6 +- tools/gitlab/image.docker | 1 + 7 files changed, 200 insertions(+), 19 deletions(-)
diff --git a/configure b/configure index 647a1237469..030235016c0 100755 --- a/configure +++ b/configure @@ -702,6 +702,8 @@ INOTIFY_LIBS INOTIFY_CFLAGS PCSCLITE_LIBS PCAP_LIBS +WAYLAND_SCANNER +WAYLAND_PROTOCOLS_DATADIR WAYLAND_CLIENT_LIBS WAYLAND_CLIENT_CFLAGS X_EXTRA_LIBS @@ -1751,6 +1753,7 @@ XMKMF CPP WAYLAND_CLIENT_CFLAGS WAYLAND_CLIENT_LIBS +WAYLAND_PROTOCOLS_DATADIR INOTIFY_CFLAGS INOTIFY_LIBS DBUS_CFLAGS @@ -2560,6 +2563,8 @@ Some influential environment variables: C compiler flags for wayland-client, overriding pkg-config WAYLAND_CLIENT_LIBS Linker flags for wayland-client, overriding pkg-config + WAYLAND_PROTOCOLS_DATADIR + Wayland protocols data directory, overriding pkg-config INOTIFY_CFLAGS C compiler flags for libinotify, overriding pkg-config INOTIFY_LIBS @@ -6251,7 +6256,7 @@ printf "%s\n" "$wine_cv_cc_m32" >&6; } host_cpu="i386" notice_platform="32-bit " TARGETFLAGS="$TARGETFLAGS -m32" - PKG_CONFIG_LIBDIR=${PKG_CONFIG_LIBDIR:-/usr/lib/i386-linux-gnu/pkgconfig:/usr/lib32/pkgconfig:/usr/lib/pkgconfig} + PKG_CONFIG_LIBDIR=${PKG_CONFIG_LIBDIR:-/usr/lib/i386-linux-gnu/pkgconfig:/usr/lib32/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig} export PKG_CONFIG_LIBDIR with_unwind=${with_unwind:-no} else @@ -15640,13 +15645,67 @@ fi
CPPFLAGS=$ac_save_CPPFLAGS
+ + if test -z "$WAYLAND_PROTOCOLS_DATADIR" -a -n "$PKG_CONFIG" + then + WAYLAND_PROTOCOLS_DATADIR=`$PKG_CONFIG --atleast-version=1.14 wayland-protocols && \ + $PKG_CONFIG --variable=pkgdatadir wayland-protocols` + fi + # Extract the first word of "wayland-scanner", so it can be a program name with args. +set dummy wayland-scanner; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_WAYLAND_SCANNER+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $WAYLAND_SCANNER in + [\/]* | ?:[\/]*) + ac_cv_path_WAYLAND_SCANNER="$WAYLAND_SCANNER" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_WAYLAND_SCANNER="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_WAYLAND_SCANNER" && ac_cv_path_WAYLAND_SCANNER="`test -n "$PKG_CONFIG" && $PKG_CONFIG --variable=wayland_scanner wayland-scanner`" + ;; +esac +fi +WAYLAND_SCANNER=$ac_cv_path_WAYLAND_SCANNER +if test -n "$WAYLAND_SCANNER"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $WAYLAND_SCANNER" >&5 +printf "%s\n" "$WAYLAND_SCANNER" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + fi -if test -z "$WAYLAND_CLIENT_LIBS" +if test -z "$WAYLAND_CLIENT_LIBS" || + test -z "$WAYLAND_PROTOCOLS_DATADIR" || + test -z "$WAYLAND_SCANNER" then : case "x$with_wayland" in - x) as_fn_append wine_notices "|Wayland ${notice_platform}development files not found, the Wayland driver won't be supported." ;; + x) as_fn_append wine_notices "|Wayland ${notice_platform}development files not found or not new enough, the Wayland driver won't be supported." ;; xno) ;; - *) as_fn_error $? "Wayland ${notice_platform}development files not found, the Wayland driver won't be supported. + *) as_fn_error $? "Wayland ${notice_platform}development files not found or not new enough, the Wayland driver won't be supported. This is an error since --with-wayland was requested." "$LINENO" 5 ;; esac enable_winewayland_drv=${enable_winewayland_drv:-no} @@ -23147,6 +23206,8 @@ X_LIBS = $X_LIBS X_EXTRA_LIBS = $X_EXTRA_LIBS WAYLAND_CLIENT_CFLAGS = $WAYLAND_CLIENT_CFLAGS WAYLAND_CLIENT_LIBS = $WAYLAND_CLIENT_LIBS +WAYLAND_PROTOCOLS_DATADIR = $WAYLAND_PROTOCOLS_DATADIR +WAYLAND_SCANNER = $WAYLAND_SCANNER PCAP_LIBS = $PCAP_LIBS PCSCLITE_LIBS = $PCSCLITE_LIBS INOTIFY_CFLAGS = $INOTIFY_CFLAGS diff --git a/configure.ac b/configure.ac index 5ff1bb093f4..379b043bf34 100644 --- a/configure.ac +++ b/configure.ac @@ -130,7 +130,7 @@ case $host in host_cpu="i386" notice_platform="32-bit " TARGETFLAGS="$TARGETFLAGS -m32" - PKG_CONFIG_LIBDIR=${PKG_CONFIG_LIBDIR:-/usr/lib/i386-linux-gnu/pkgconfig:/usr/lib32/pkgconfig:/usr/lib/pkgconfig} + PKG_CONFIG_LIBDIR=${PKG_CONFIG_LIBDIR:-/usr/lib/i386-linux-gnu/pkgconfig:/usr/lib32/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig} export PKG_CONFIG_LIBDIR with_unwind=${with_unwind:-no} else @@ -1342,9 +1342,20 @@ then [AC_CHECK_HEADERS([wayland-client.h]) AC_CHECK_LIB(wayland-client,wl_display_connect,[:], [WAYLAND_CLIENT_LIBS=""],[$WAYLAND_CLIENT_LIBS])]) + AC_ARG_VAR(WAYLAND_PROTOCOLS_DATADIR, + [Wayland protocols data directory, overriding pkg-config]) + if test -z "$WAYLAND_PROTOCOLS_DATADIR" -a -n "$PKG_CONFIG" + then + WAYLAND_PROTOCOLS_DATADIR=`$PKG_CONFIG --atleast-version=1.14 wayland-protocols && \ + $PKG_CONFIG --variable=pkgdatadir wayland-protocols` + fi + AC_PATH_PROG(WAYLAND_SCANNER,wayland-scanner, + [`test -n "$PKG_CONFIG" && $PKG_CONFIG --variable=wayland_scanner wayland-scanner`]) fi -WINE_NOTICE_WITH(wayland, [test -z "$WAYLAND_CLIENT_LIBS"], - [Wayland ${notice_platform}development files not found, the Wayland driver won't be supported.], +WINE_NOTICE_WITH(wayland, [test -z "$WAYLAND_CLIENT_LIBS" || + test -z "$WAYLAND_PROTOCOLS_DATADIR" || + test -z "$WAYLAND_SCANNER"], + [Wayland ${notice_platform}development files not found or not new enough, the Wayland driver won't be supported.], [enable_winewayland_drv])
dnl **** Check for OpenCL **** diff --git a/dlls/winewayland.drv/Makefile.in b/dlls/winewayland.drv/Makefile.in index d86b51a519f..824c594bc98 100644 --- a/dlls/winewayland.drv/Makefile.in +++ b/dlls/winewayland.drv/Makefile.in @@ -10,4 +10,7 @@ C_SRCS = \ wayland_output.c \ waylanddrv_main.c
+WAYLAND_PROTOCOL_SRCS = \ + $(WAYLAND_PROTOCOLS_DATADIR)/unstable/xdg-output/xdg-output-unstable-v1.xml + RC_SRCS = version.rc diff --git a/dlls/winewayland.drv/wayland.c b/dlls/winewayland.drv/wayland.c index 104a091ea80..30ef22df52d 100644 --- a/dlls/winewayland.drv/wayland.c +++ b/dlls/winewayland.drv/wayland.c @@ -50,6 +50,18 @@ static void registry_handle_global(void *data, struct wl_registry *registry, if (!wayland_output_create(id, version)) ERR("Failed to create wayland_output for global id=%u\n", id); } + else if (strcmp(interface, "zxdg_output_manager_v1") == 0) + { + struct wayland_output *output; + + process_wayland->zxdg_output_manager_v1 = + wl_registry_bind(registry, id, &zxdg_output_manager_v1_interface, + version < 3 ? version : 3); + + /* Add zxdg_output_v1 to existing outputs. */ + wl_list_for_each(output, &process_wayland->output_list, link) + wayland_output_use_xdg_extension(output); + } }
static void registry_handle_global_remove(void *data, struct wl_registry *registry, diff --git a/dlls/winewayland.drv/wayland_output.c b/dlls/winewayland.drv/wayland_output.c index be9ea32bd72..8eb24fe97f3 100644 --- a/dlls/winewayland.drv/wayland_output.c +++ b/dlls/winewayland.drv/wayland_output.c @@ -97,6 +97,22 @@ static void wayland_output_add_mode(struct wayland_output *output, if (current) output->current_mode = mode; }
+static void wayland_output_done(struct wayland_output *output) +{ + struct wayland_output_mode *mode; + + TRACE("name=%s\n", output->name); + + RB_FOR_EACH_ENTRY(mode, &output->modes, struct wayland_output_mode, entry) + { + TRACE("mode %dx%d @ %d %s\n", + mode->width, mode->height, mode->refresh, + output->current_mode == mode ? "*" : ""); + } + + wayland_init_display_devices(); +} + static void output_handle_geometry(void *data, struct wl_output *wl_output, int32_t x, int32_t y, int32_t physical_width, int32_t physical_height, @@ -122,18 +138,12 @@ static void output_handle_mode(void *data, struct wl_output *wl_output, static void output_handle_done(void *data, struct wl_output *wl_output) { struct wayland_output *output = data; - struct wayland_output_mode *mode; - - TRACE("name=%s\n", output->name);
- RB_FOR_EACH_ENTRY(mode, &output->modes, struct wayland_output_mode, entry) + if (!output->zxdg_output_v1 || + zxdg_output_v1_get_version(output->zxdg_output_v1) >= 3) { - TRACE("mode %dx%d @ %d %s\n", - mode->width, mode->height, mode->refresh, - output->current_mode == mode ? "*" : ""); + wayland_output_done(output); } - - wayland_init_display_devices(); }
static void output_handle_scale(void *data, struct wl_output *wl_output, @@ -148,6 +158,54 @@ static const struct wl_output_listener output_listener = { output_handle_scale };
+static void zxdg_output_v1_handle_logical_position(void *data, + struct zxdg_output_v1 *zxdg_output_v1, + int32_t x, + int32_t y) +{ +} + +static void zxdg_output_v1_handle_logical_size(void *data, + struct zxdg_output_v1 *zxdg_output_v1, + int32_t width, + int32_t height) +{ +} + +static void zxdg_output_v1_handle_done(void *data, + struct zxdg_output_v1 *zxdg_output_v1) +{ + if (zxdg_output_v1_get_version(zxdg_output_v1) < 3) + { + struct wayland_output *output = data; + wayland_output_done(output); + } +} + +static void zxdg_output_v1_handle_name(void *data, + struct zxdg_output_v1 *zxdg_output_v1, + const char *name) +{ + struct wayland_output *output = data; + + free(output->name); + output->name = strdup(name); +} + +static void zxdg_output_v1_handle_description(void *data, + struct zxdg_output_v1 *zxdg_output_v1, + const char *description) +{ +} + +static const struct zxdg_output_v1_listener zxdg_output_v1_listener = { + zxdg_output_v1_handle_logical_position, + zxdg_output_v1_handle_logical_size, + zxdg_output_v1_handle_done, + zxdg_output_v1_handle_name, + zxdg_output_v1_handle_description, +}; + /********************************************************************** * wayland_output_create * @@ -156,6 +214,7 @@ static const struct wl_output_listener output_listener = { BOOL wayland_output_create(uint32_t id, uint32_t version) { struct wayland_output *output = calloc(1, sizeof(*output)); + int name_len;
if (!output) { @@ -172,8 +231,21 @@ BOOL wayland_output_create(uint32_t id, uint32_t version) wl_list_init(&output->link); rb_init(&output->modes, wayland_output_mode_cmp_rb);
- snprintf(output->name, sizeof(output->name), "WaylandOutput%d", - next_output_id++); + /* Have a fallback while we don't have compositor given name. */ + name_len = snprintf(NULL, 0, "WaylandOutput%d", next_output_id); + output->name = malloc(name_len + 1); + if (output->name) + { + snprintf(output->name, name_len + 1, "WaylandOutput%d", next_output_id++); + } + else + { + ERR("Couldn't allocate space for output name\n"); + goto err; + } + + if (process_wayland->zxdg_output_manager_v1) + wayland_output_use_xdg_extension(output);
wl_list_insert(process_wayland->output_list.prev, &output->link);
@@ -198,6 +270,23 @@ void wayland_output_destroy(struct wayland_output *output) { rb_destroy(&output->modes, wayland_output_mode_free_rb, NULL); wl_list_remove(&output->link); + if (output->zxdg_output_v1) + zxdg_output_v1_destroy(output->zxdg_output_v1); wl_output_destroy(output->wl_output); + free(output->name); free(output); } + +/********************************************************************** + * wayland_output_use_xdg_extension + * + * Use the zxdg_output_v1 extension to get output information. + */ +void wayland_output_use_xdg_extension(struct wayland_output *output) +{ + output->zxdg_output_v1 = + zxdg_output_manager_v1_get_xdg_output(process_wayland->zxdg_output_manager_v1, + output->wl_output); + zxdg_output_v1_add_listener(output->zxdg_output_v1, &zxdg_output_v1_listener, + output); +} diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 8458ed17df2..da0fccecda9 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -26,6 +26,7 @@ #endif
#include <wayland-client.h> +#include "xdg-output-unstable-v1-client-protocol.h"
#include "windef.h" #include "winbase.h" @@ -49,6 +50,7 @@ struct wayland { struct wl_event_queue *wl_event_queue; struct wl_registry *wl_registry; + struct zxdg_output_manager_v1 *zxdg_output_manager_v1; struct wl_list output_list; };
@@ -64,9 +66,10 @@ struct wayland_output { struct wl_list link; struct wl_output *wl_output; + struct zxdg_output_v1 *zxdg_output_v1; struct rb_tree modes; struct wayland_output_mode *current_mode; - char name[20]; + char *name; uint32_t global_id; };
@@ -83,6 +86,7 @@ void wayland_init_display_devices(void) DECLSPEC_HIDDEN;
BOOL wayland_output_create(uint32_t id, uint32_t version) DECLSPEC_HIDDEN; void wayland_output_destroy(struct wayland_output *output) DECLSPEC_HIDDEN; +void wayland_output_use_xdg_extension(struct wayland_output *output) DECLSPEC_HIDDEN;
/********************************************************************** * USER driver functions diff --git a/tools/gitlab/image.docker b/tools/gitlab/image.docker index cf16ed49c95..7e8d69170c1 100644 --- a/tools/gitlab/image.docker +++ b/tools/gitlab/image.docker @@ -51,6 +51,7 @@ RUN export DEBIAN_FRONTEND=noninteractive; \ ocl-icd-opencl-dev:amd64 ocl-icd-opencl-dev:i386 \ samba-dev:amd64 \ unixodbc-dev:amd64 unixodbc-dev:i386 \ + wayland-protocols \ x11proto-dev && \ apt-get install -y ccache netbase curl ca-certificates xserver-xorg-video-dummy xserver-xorg xfonts-base xinit fvwm \ winbind fonts-liberation2 fonts-noto-core fonts-noto-cjk pulseaudio libasound2-plugins:amd64 libasound2-plugins:i386 \