Introduction ------------
This is the first of (many) parts in the upstreaming of the Wayland driver for Wine. Since the amount of code and commits is large, my approach is to upstream the driver in multiple parts in a serial fashion, with each part being a cohesive (to the degree possible) set of not too many commits. When each part is reviewed and merged, I will move on to proposing the next part. My main goal with this approach is to make reviewing easier and more focused. If you have other ideas about how to improve this process for the reviewers, please let me know.
A lot of pieces need to fall into place before the driver becomes even remotely functional, so, some MRs (especially the initial ones) will be a bit more preparatory in nature. To aid in the understanding of and justification for some of the code introduced in such MRs, all the remaining driver commits are always going to be available at https://gitlab.winehq.org/afrantzis/wine/-/tree/wayland.
Part 1 -------
This MR introduces the Wayland driver PE and unixlib components with some basic code, and prepares the makedep tool to be able to handle Wayland protocol files. Please see the individual commit message for more details.
Some questions I would appreciate some feedback on in the context of this MR:
1. Should the Wayland driver build be enabled by default at this point? (currently it's explicitly opt-in with --with-wayland) 2. How should the Wayland driver build be integrated with CI? (currently piggybacking on gitlab/build-linux by adding --with-wayland)
Note that building the Wayland driver should not affect running/testing on X11/Xwayland etc, since it's placed lower in the driver priority list.
Part 2 preview: We will handle basic Wayland wl_output (i.e., display) events and populate the Wine monitor information.
From: Alexandros Frantzis alexandros.frantzis@collabora.com
Add the initial driver stub for the Wayland driver and enable building it with the '--with-wayland' configure flag (building the driver is disabled by default).
Enable building the driver as part of gitlab CI.
Signed-off-by: Alexandros Frantzis alexandros.frantzis@collabora.com --- configure | 28 +++++++++++++++++++++ configure.ac | 11 +++++++++ dlls/winewayland.drv/Makefile.in | 6 +++++ dlls/winewayland.drv/dllmain.c | 30 +++++++++++++++++++++++ dlls/winewayland.drv/version.rc | 22 +++++++++++++++++ dlls/winewayland.drv/waylanddrv_dll.h | 28 +++++++++++++++++++++ dlls/winewayland.drv/winewayland.drv.spec | 0 tools/gitlab/build-linux | 4 +-- 8 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 dlls/winewayland.drv/Makefile.in create mode 100644 dlls/winewayland.drv/dllmain.c create mode 100644 dlls/winewayland.drv/version.rc create mode 100644 dlls/winewayland.drv/waylanddrv_dll.h create mode 100644 dlls/winewayland.drv/winewayland.drv.spec
diff --git a/configure b/configure index 922b3a3640e..83231b1c52b 100755 --- a/configure +++ b/configure @@ -939,6 +939,7 @@ with_unwind with_usb with_v4l2 with_vulkan +with_wayland with_xcomposite with_xcursor with_xfixes @@ -1474,6 +1475,7 @@ enable_wineps_drv enable_winepulse_drv enable_wineusb_sys enable_winevulkan +enable_winewayland_drv enable_winex11_drv enable_winexinput_sys enable_wing32 @@ -2458,6 +2460,7 @@ Optional Packages: --without-usb do not use the libusb library --without-v4l2 do not use v4l2 (video capture) --without-vulkan do not use Vulkan + --with-wayland build with wayland support --without-xcomposite do not use the Xcomposite extension --without-xcursor do not use the Xcursor extension --without-xfixes do not use Xfixes for clipboard change notifications @@ -4381,6 +4384,15 @@ then : fi
+# Check whether --with-wayland was given. +if test ${with_wayland+y} +then : + withval=$with_wayland; +else $as_nop + with_wayland=no +fi + + # Check whether --with-xcomposite was given. if test ${with_xcomposite+y} then : @@ -15661,6 +15673,21 @@ enable_winex11_drv=${enable_winex11_drv:-no} fi fi
+if test "x$with_wayland" = "xno" +then + enable_winewayland_drv=no +fi +if false +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." ;; + xno) ;; + *) as_fn_error $? "Wayland ${notice_platform}development files not found, 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} +fi + if test "$ac_cv_header_CL_cl_h" = "yes" then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for clGetPlatformInfo in -lOpenCL" >&5 @@ -21850,6 +21877,7 @@ wine_fn_config_makefile dlls/wineps16.drv16 enable_win16 wine_fn_config_makefile dlls/winepulse.drv enable_winepulse_drv wine_fn_config_makefile dlls/wineusb.sys enable_wineusb_sys wine_fn_config_makefile dlls/winevulkan enable_winevulkan +wine_fn_config_makefile dlls/winewayland.drv enable_winewayland_drv wine_fn_config_makefile dlls/winex11.drv enable_winex11_drv wine_fn_config_makefile dlls/winexinput.sys enable_winexinput_sys wine_fn_config_makefile dlls/wing.dll16 enable_win16 diff --git a/configure.ac b/configure.ac index 16bada50512..29ec91b93f2 100644 --- a/configure.ac +++ b/configure.ac @@ -61,6 +61,8 @@ AC_ARG_WITH(unwind, AS_HELP_STRING([--without-unwind],[do not use the libunwi AC_ARG_WITH(usb, AS_HELP_STRING([--without-usb],[do not use the libusb library])) AC_ARG_WITH(v4l2, AS_HELP_STRING([--without-v4l2],[do not use v4l2 (video capture)])) AC_ARG_WITH(vulkan, AS_HELP_STRING([--without-vulkan],[do not use Vulkan])) +AC_ARG_WITH(wayland, AS_HELP_STRING([--with-wayland],[build with wayland support]), + [], [with_wayland=no]) AC_ARG_WITH(xcomposite,AS_HELP_STRING([--without-xcomposite],[do not use the Xcomposite extension]), [if test "x$withval" = "xno"; then ac_cv_header_X11_extensions_Xcomposite_h=no; fi]) AC_ARG_WITH(xcursor, AS_HELP_STRING([--without-xcursor],[do not use the Xcursor extension]), @@ -1360,6 +1362,14 @@ else [enable_winex11_drv]) fi
+if test "x$with_wayland" = "xno" +then + enable_winewayland_drv=no +fi +WINE_NOTICE_WITH(wayland, [false], + [Wayland ${notice_platform}development files not found, the Wayland driver won't be supported.], + [enable_winewayland_drv]) + dnl **** Check for OpenCL **** if test "$ac_cv_header_CL_cl_h" = "yes" then @@ -3163,6 +3173,7 @@ WINE_CONFIG_MAKEFILE(dlls/wineps16.drv16,enable_win16) WINE_CONFIG_MAKEFILE(dlls/winepulse.drv) WINE_CONFIG_MAKEFILE(dlls/wineusb.sys) WINE_CONFIG_MAKEFILE(dlls/winevulkan) +WINE_CONFIG_MAKEFILE(dlls/winewayland.drv) WINE_CONFIG_MAKEFILE(dlls/winex11.drv) WINE_CONFIG_MAKEFILE(dlls/winexinput.sys) WINE_CONFIG_MAKEFILE(dlls/wing.dll16,enable_win16) diff --git a/dlls/winewayland.drv/Makefile.in b/dlls/winewayland.drv/Makefile.in new file mode 100644 index 00000000000..713b281b1bd --- /dev/null +++ b/dlls/winewayland.drv/Makefile.in @@ -0,0 +1,6 @@ +MODULE = winewayland.drv + +C_SRCS = \ + dllmain.c \ + +RC_SRCS = version.rc diff --git a/dlls/winewayland.drv/dllmain.c b/dlls/winewayland.drv/dllmain.c new file mode 100644 index 00000000000..7ab3341e61d --- /dev/null +++ b/dlls/winewayland.drv/dllmain.c @@ -0,0 +1,30 @@ +/* + * winewayland.drv entry points + * + * Copyright 2022 Alexandros Frantzis for Collabora Ltd + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "waylanddrv_dll.h" + +BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved) +{ + if (reason != DLL_PROCESS_ATTACH) return TRUE; + + DisableThreadLibraryCalls(instance); + + return TRUE; +} diff --git a/dlls/winewayland.drv/version.rc b/dlls/winewayland.drv/version.rc new file mode 100644 index 00000000000..2d99c24f99c --- /dev/null +++ b/dlls/winewayland.drv/version.rc @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2020 Alexandros Frantzis for Collabora Ltd + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define WINE_FILEDESCRIPTION_STR "Wine Wayland driver" +#define WINE_FILENAME_STR "winewayland.drv" + +#include "wine/wine_common_ver.rc" diff --git a/dlls/winewayland.drv/waylanddrv_dll.h b/dlls/winewayland.drv/waylanddrv_dll.h new file mode 100644 index 00000000000..556898d44b2 --- /dev/null +++ b/dlls/winewayland.drv/waylanddrv_dll.h @@ -0,0 +1,28 @@ +/* + * Wayland driver DLL definitions + * + * Copyright 2022 Alexandros Frantzis for Collabora Ltd + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WINE_WAYLANDDRV_DLL_H +#define __WINE_WAYLANDDRV_DLL_H + +#include <stdarg.h> +#include "windef.h" +#include "winbase.h" + +#endif /* __WINE_WAYLANDDRV_DLL_H */ diff --git a/dlls/winewayland.drv/winewayland.drv.spec b/dlls/winewayland.drv/winewayland.drv.spec new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tools/gitlab/build-linux b/tools/gitlab/build-linux index d77ca9cdb8e..dbb2986be1b 100755 --- a/tools/gitlab/build-linux +++ b/tools/gitlab/build-linux @@ -10,12 +10,12 @@ set -Eeuxo pipefail autoreconf -f
cd build64 -../configure -q -C --enable-win64 --enable-werror --with-mingw +../configure -q -C --enable-win64 --enable-werror --with-mingw --with-wayland make -s -j$(nproc) cd ..
cd build32 -../configure -q -C --enable-werror --with-mingw +../configure -q -C --enable-werror --with-mingw --with-wayland make -s -j$(nproc) cd ..
From: Alexandros Frantzis alexandros.frantzis@collabora.com
Signed-off-by: Alexandros Frantzis alexandros.frantzis@collabora.com --- dlls/winewayland.drv/Makefile.in | 2 + dlls/winewayland.drv/dllmain.c | 4 ++ dlls/winewayland.drv/unixlib.h | 32 ++++++++++++++++ dlls/winewayland.drv/waylanddrv.h | 30 +++++++++++++++ dlls/winewayland.drv/waylanddrv_dll.h | 4 ++ dlls/winewayland.drv/waylanddrv_main.c | 53 ++++++++++++++++++++++++++ 6 files changed, 125 insertions(+) create mode 100644 dlls/winewayland.drv/unixlib.h create mode 100644 dlls/winewayland.drv/waylanddrv.h create mode 100644 dlls/winewayland.drv/waylanddrv_main.c
diff --git a/dlls/winewayland.drv/Makefile.in b/dlls/winewayland.drv/Makefile.in index 713b281b1bd..1d52f466c41 100644 --- a/dlls/winewayland.drv/Makefile.in +++ b/dlls/winewayland.drv/Makefile.in @@ -1,6 +1,8 @@ MODULE = winewayland.drv +UNIXLIB = winewayland.so
C_SRCS = \ dllmain.c \ + waylanddrv_main.c \
RC_SRCS = version.rc diff --git a/dlls/winewayland.drv/dllmain.c b/dlls/winewayland.drv/dllmain.c index 7ab3341e61d..89d981a4314 100644 --- a/dlls/winewayland.drv/dllmain.c +++ b/dlls/winewayland.drv/dllmain.c @@ -25,6 +25,10 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved) if (reason != DLL_PROCESS_ATTACH) return TRUE;
DisableThreadLibraryCalls(instance); + if (__wine_init_unix_call()) return FALSE; + + if (WAYLANDDRV_UNIX_CALL(init, NULL)) + return FALSE;
return TRUE; } diff --git a/dlls/winewayland.drv/unixlib.h b/dlls/winewayland.drv/unixlib.h new file mode 100644 index 00000000000..427837523e3 --- /dev/null +++ b/dlls/winewayland.drv/unixlib.h @@ -0,0 +1,32 @@ +/* + * Copyright 2022 Alexandros Frantzis for Collabora Ltd + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WINE_WAYLANDDRV_UNIXLIB_H +#define __WINE_WAYLANDDRV_UNIXLIB_H + +#include <stdarg.h> +#include "winternl.h" +#include "wine/unixlib.h" + +enum waylanddrv_unix_func +{ + waylanddrv_unix_func_init, + waylanddrv_unix_func_count, +}; + +#endif /* __WINE_WAYLANDDRV_UNIXLIB_H */ diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h new file mode 100644 index 00000000000..ec656ea87fb --- /dev/null +++ b/dlls/winewayland.drv/waylanddrv.h @@ -0,0 +1,30 @@ +/* + * Wayland driver + * + * Copyright 2020 Alexandros Frantzis for Collabora Ltd + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WINE_WAYLANDDRV_H +#define __WINE_WAYLANDDRV_H + +#ifndef __WINE_CONFIG_H +# error You must include config.h to use this header +#endif + +#include "unixlib.h" + +#endif /* __WINE_WAYLANDDRV_H */ diff --git a/dlls/winewayland.drv/waylanddrv_dll.h b/dlls/winewayland.drv/waylanddrv_dll.h index 556898d44b2..123b6cd5a61 100644 --- a/dlls/winewayland.drv/waylanddrv_dll.h +++ b/dlls/winewayland.drv/waylanddrv_dll.h @@ -25,4 +25,8 @@ #include "windef.h" #include "winbase.h"
+#include "unixlib.h" + +#define WAYLANDDRV_UNIX_CALL(func, params) WINE_UNIX_CALL(waylanddrv_unix_func_ ## func, params) + #endif /* __WINE_WAYLANDDRV_DLL_H */ diff --git a/dlls/winewayland.drv/waylanddrv_main.c b/dlls/winewayland.drv/waylanddrv_main.c new file mode 100644 index 00000000000..396beac5828 --- /dev/null +++ b/dlls/winewayland.drv/waylanddrv_main.c @@ -0,0 +1,53 @@ +/* + * WAYLANDDRV initialization code + * + * Copyright 2020 Alexandre Frantzis for Collabora Ltd + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#if 0 +#pragma makedep unix +#endif + +#include "config.h" + +#include "ntstatus.h" +#define WIN32_NO_STATUS + +#include "waylanddrv.h" + +static NTSTATUS waylanddrv_unix_init(void *arg) +{ + return 0; +} + +const unixlib_entry_t __wine_unix_call_funcs[] = +{ + waylanddrv_unix_init, +}; + +C_ASSERT(ARRAYSIZE(__wine_unix_call_funcs) == waylanddrv_unix_func_count); + +#ifdef _WIN64 + +const unixlib_entry_t __wine_unix_call_wow64_funcs[] = +{ + waylanddrv_unix_init, +}; + +C_ASSERT(ARRAYSIZE(__wine_unix_call_wow64_funcs) == waylanddrv_unix_func_count); + +#endif /* _WIN64 */
From: Alexandros Frantzis alexandros.frantzis@collabora.com
Add the Wayland driver at the end of the default driver list. This ensures that, by default, under Wayland compositors that support Xwayland, the more mature X11 driver will be used. One can force using the wayland driver by ensuring X11 is not accessible, e.g., by unsetting the DISPLAY environment variable.
Signed-off-by: Alexandros Frantzis alexandros.frantzis@collabora.com --- programs/explorer/desktop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/programs/explorer/desktop.c b/programs/explorer/desktop.c index 96673adc254..afa711a8dbf 100644 --- a/programs/explorer/desktop.c +++ b/programs/explorer/desktop.c @@ -40,7 +40,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(explorer); #define DESKTOP_CLASS_ATOM ((LPCWSTR)MAKEINTATOM(32769)) #define DESKTOP_ALL_ACCESS 0x01ff
-static const WCHAR default_driver[] = {'m','a','c',',','x','1','1',0}; +static const WCHAR default_driver[] = {'m','a','c',',','x','1','1',',','w','a','y','l','a','n','d',0};
static BOOL using_root;
From: Alexandros Frantzis alexandros.frantzis@collabora.com
Try to connect to the Wayland compositor, and fail driver initialization if we are unable to do so.
Signed-off-by: Alexandros Frantzis alexandros.frantzis@collabora.com --- configure | 91 +++++++++++++++++++++++++- configure.ac | 7 +- dlls/winewayland.drv/Makefile.in | 3 + dlls/winewayland.drv/wayland.c | 41 ++++++++++++ dlls/winewayland.drv/waylanddrv.h | 14 ++++ dlls/winewayland.drv/waylanddrv_main.c | 2 + include/config.h.in | 3 + tools/gitlab/image.docker | 1 + 8 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 dlls/winewayland.drv/wayland.c
diff --git a/configure b/configure index 83231b1c52b..4d9030e610e 100755 --- a/configure +++ b/configure @@ -702,6 +702,8 @@ INOTIFY_LIBS INOTIFY_CFLAGS PCSCLITE_LIBS PCAP_LIBS +WAYLAND_CLIENT_LIBS +WAYLAND_CLIENT_CFLAGS X_EXTRA_LIBS X_LIBS X_PRE_LIBS @@ -1746,6 +1748,8 @@ ZLIB_PE_CFLAGS ZLIB_PE_LIBS XMKMF CPP +WAYLAND_CLIENT_CFLAGS +WAYLAND_CLIENT_LIBS INOTIFY_CFLAGS INOTIFY_LIBS DBUS_CFLAGS @@ -2546,6 +2550,10 @@ Some influential environment variables: Linker flags for the PE zlib, overriding the bundled version XMKMF Path to xmkmf, Makefile generator for X Window System CPP C preprocessor + WAYLAND_CLIENT_CFLAGS + C compiler flags for wayland-client, overriding pkg-config + WAYLAND_CLIENT_LIBS + Linker flags for wayland-client, overriding pkg-config INOTIFY_CFLAGS C compiler flags for libinotify, overriding pkg-config INOTIFY_LIBS @@ -15676,8 +15684,87 @@ fi if test "x$with_wayland" = "xno" then enable_winewayland_drv=no +else + rm -f conftest.err +if ${WAYLAND_CLIENT_CFLAGS:+false} : +then : + if test ${PKG_CONFIG+y} +then : + WAYLAND_CLIENT_CFLAGS=`$PKG_CONFIG --cflags wayland-client 2>conftest.err` +fi +fi + +if ${WAYLAND_CLIENT_LIBS:+false} : +then : + if test ${PKG_CONFIG+y} +then : + WAYLAND_CLIENT_LIBS=`$PKG_CONFIG --libs wayland-client 2>/dev/null` +fi +fi + + +printf "%s\n" "$as_me:${as_lineno-$LINENO}: wayland-client cflags: $WAYLAND_CLIENT_CFLAGS" >&5 +printf "%s\n" "$as_me:${as_lineno-$LINENO}: wayland-client libs: $WAYLAND_CLIENT_LIBS" >&5 +if test -s conftest.err; then + printf %s "$as_me:${as_lineno-$LINENO}: wayland-client errors: " >&5 + cat conftest.err >&5 +fi +rm -f conftest.err +ac_save_CPPFLAGS=$CPPFLAGS +CPPFLAGS="$CPPFLAGS $WAYLAND_CLIENT_CFLAGS" +ac_fn_c_check_header_compile "$LINENO" "wayland-client.h" "ac_cv_header_wayland_client_h" "$ac_includes_default" +if test "x$ac_cv_header_wayland_client_h" = xyes +then : + printf "%s\n" "#define HAVE_WAYLAND_CLIENT_H 1" >>confdefs.h + +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for wl_display_connect in -lwayland-client" >&5 +printf %s "checking for wl_display_connect in -lwayland-client... " >&6; } +if test ${ac_cv_lib_wayland_client_wl_display_connect+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lwayland-client $WAYLAND_CLIENT_LIBS $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char wl_display_connect (); +int +main (void) +{ +return wl_display_connect (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_wayland_client_wl_display_connect=yes +else $as_nop + ac_cv_lib_wayland_client_wl_display_connect=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_wayland_client_wl_display_connect" >&5 +printf "%s\n" "$ac_cv_lib_wayland_client_wl_display_connect" >&6; } +if test "x$ac_cv_lib_wayland_client_wl_display_connect" = xyes +then : + : +else $as_nop + WAYLAND_CLIENT_LIBS="" +fi + +CPPFLAGS=$ac_save_CPPFLAGS + fi -if false +if test -z "$WAYLAND_CLIENT_LIBS" 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." ;; @@ -23181,6 +23268,8 @@ X_CFLAGS = $X_CFLAGS X_PRE_LIBS = $X_PRE_LIBS X_LIBS = $X_LIBS X_EXTRA_LIBS = $X_EXTRA_LIBS +WAYLAND_CLIENT_CFLAGS = $WAYLAND_CLIENT_CFLAGS +WAYLAND_CLIENT_LIBS = $WAYLAND_CLIENT_LIBS PCAP_LIBS = $PCAP_LIBS PCSCLITE_LIBS = $PCSCLITE_LIBS INOTIFY_CFLAGS = $INOTIFY_CFLAGS diff --git a/configure.ac b/configure.ac index 29ec91b93f2..bde4f1a1e24 100644 --- a/configure.ac +++ b/configure.ac @@ -1365,8 +1365,13 @@ fi if test "x$with_wayland" = "xno" then enable_winewayland_drv=no +else + WINE_PACKAGE_FLAGS(WAYLAND_CLIENT,[wayland-client],,,, + [AC_CHECK_HEADERS([wayland-client.h]) + AC_CHECK_LIB(wayland-client,wl_display_connect,[:], + [WAYLAND_CLIENT_LIBS=""],[$WAYLAND_CLIENT_LIBS])]) fi -WINE_NOTICE_WITH(wayland, [false], +WINE_NOTICE_WITH(wayland, [test -z "$WAYLAND_CLIENT_LIBS"], [Wayland ${notice_platform}development files not found, the Wayland driver won't be supported.], [enable_winewayland_drv])
diff --git a/dlls/winewayland.drv/Makefile.in b/dlls/winewayland.drv/Makefile.in index 1d52f466c41..fc1fe8119ec 100644 --- a/dlls/winewayland.drv/Makefile.in +++ b/dlls/winewayland.drv/Makefile.in @@ -1,8 +1,11 @@ MODULE = winewayland.drv UNIXLIB = winewayland.so +UNIX_CFLAGS = $(WAYLAND_CLIENT_CFLAGS) +UNIX_LIBS = $(WAYLAND_CLIENT_LIBS)
C_SRCS = \ dllmain.c \ + wayland.c \ waylanddrv_main.c \
RC_SRCS = version.rc diff --git a/dlls/winewayland.drv/wayland.c b/dlls/winewayland.drv/wayland.c new file mode 100644 index 00000000000..9b61427c8aa --- /dev/null +++ b/dlls/winewayland.drv/wayland.c @@ -0,0 +1,41 @@ +/* + * Wayland core handling + * + * Copyright (c) 2020 Alexandros Frantzis for Collabora Ltd + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#if 0 +#pragma makedep unix +#endif + +#include "config.h" + +#include "waylanddrv.h" + +struct wl_display *process_wl_display = NULL; + +/********************************************************************** + * wayland_process_init + * + * Initialise the per process wayland objects. + * + */ +BOOL wayland_process_init(void) +{ + process_wl_display = wl_display_connect(NULL); + return process_wl_display != NULL; +} diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index ec656ea87fb..3fd8728d81b 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -25,6 +25,20 @@ # error You must include config.h to use this header #endif
+#include <wayland-client.h> + #include "unixlib.h"
+/********************************************************************** + * Globals + */ + +extern struct wl_display *process_wl_display DECLSPEC_HIDDEN; + +/********************************************************************** + * Wayland initialization + */ + +BOOL wayland_process_init(void) DECLSPEC_HIDDEN; + #endif /* __WINE_WAYLANDDRV_H */ diff --git a/dlls/winewayland.drv/waylanddrv_main.c b/dlls/winewayland.drv/waylanddrv_main.c index 396beac5828..d4018683239 100644 --- a/dlls/winewayland.drv/waylanddrv_main.c +++ b/dlls/winewayland.drv/waylanddrv_main.c @@ -31,6 +31,8 @@
static NTSTATUS waylanddrv_unix_init(void *arg) { + if (!wayland_process_init()) return STATUS_UNSUCCESSFUL; + return 0; }
diff --git a/include/config.h.in b/include/config.h.in index fe2fc36a914..1e608d36017 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -645,6 +645,9 @@ /* Define to 1 if you have the <valgrind/valgrind.h> header file. */ #undef HAVE_VALGRIND_VALGRIND_H
+/* Define to 1 if you have the <wayland-client.h> header file. */ +#undef HAVE_WAYLAND_CLIENT_H + /* Define to 1 if you have the <X11/extensions/shape.h> header file. */ #undef HAVE_X11_EXTENSIONS_SHAPE_H
diff --git a/tools/gitlab/image.docker b/tools/gitlab/image.docker index 0d23a75483b..cf16ed49c95 100644 --- a/tools/gitlab/image.docker +++ b/tools/gitlab/image.docker @@ -37,6 +37,7 @@ RUN export DEBIAN_FRONTEND=noninteractive; \ libusb-1.0-0-dev:amd64 libusb-1.0-0-dev:i386 \ libv4l-dev:amd64 libv4l-dev:i386 \ libvulkan-dev:amd64 libvulkan-dev:i386 \ + libwayland-dev:amd64 libwayland-dev:i386 \ libx11-dev:amd64 libx11-dev:i386 \ libxcomposite-dev:amd64 libxcomposite-dev:i386 \ libxcursor-dev:amd64 libxcursor-dev:i386 \
From: Alexandros Frantzis alexandros.frantzis@collabora.com
Handle allocation and deallocation of per-thread data (currently without any actual contents).
Signed-off-by: Alexandros Frantzis alexandros.frantzis@collabora.com --- dlls/winewayland.drv/Makefile.in | 2 +- dlls/winewayland.drv/waylanddrv.h | 20 +++++++++ dlls/winewayland.drv/waylanddrv_main.c | 59 +++++++++++++++++++++++++- 3 files changed, 79 insertions(+), 2 deletions(-)
diff --git a/dlls/winewayland.drv/Makefile.in b/dlls/winewayland.drv/Makefile.in index fc1fe8119ec..ba460fcc792 100644 --- a/dlls/winewayland.drv/Makefile.in +++ b/dlls/winewayland.drv/Makefile.in @@ -1,7 +1,7 @@ MODULE = winewayland.drv UNIXLIB = winewayland.so UNIX_CFLAGS = $(WAYLAND_CLIENT_CFLAGS) -UNIX_LIBS = $(WAYLAND_CLIENT_LIBS) +UNIX_LIBS = -lwin32u $(WAYLAND_CLIENT_LIBS)
C_SRCS = \ dllmain.c \ diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 3fd8728d81b..057eb3f8350 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -25,8 +25,13 @@ # error You must include config.h to use this header #endif
+#include <stdarg.h> #include <wayland-client.h>
+#include "windef.h" +#include "winbase.h" +#include "ntuser.h" + #include "unixlib.h"
/********************************************************************** @@ -35,6 +40,21 @@
extern struct wl_display *process_wl_display DECLSPEC_HIDDEN;
+/********************************************************************** + * Wayland thread data + */ + +struct wayland_thread_data +{ +}; + +extern struct wayland_thread_data *wayland_init_thread_data(void) DECLSPEC_HIDDEN; + +static inline struct wayland_thread_data *wayland_thread_data(void) +{ + return (struct wayland_thread_data *)(UINT_PTR)NtUserGetThreadInfo()->driver_data; +} + /********************************************************************** * Wayland initialization */ diff --git a/dlls/winewayland.drv/waylanddrv_main.c b/dlls/winewayland.drv/waylanddrv_main.c index d4018683239..10410157709 100644 --- a/dlls/winewayland.drv/waylanddrv_main.c +++ b/dlls/winewayland.drv/waylanddrv_main.c @@ -29,11 +29,68 @@
#include "waylanddrv.h"
+#include "wine/debug.h" +#include "wine/gdi_driver.h" + +#include <stdlib.h> + +WINE_DEFAULT_DEBUG_CHANNEL(waylanddrv); + +/*********************************************************************** + * Initialize per thread data + */ +struct wayland_thread_data *wayland_init_thread_data(void) +{ + struct wayland_thread_data *data = wayland_thread_data(); + + if (data) return data; + + if (!(data = calloc(1, sizeof(*data)))) + { + ERR("could not create data\n"); + NtTerminateProcess(0, 1); + } + + NtUserGetThreadInfo()->driver_data = (UINT_PTR)data; + + return data; +} + +/*********************************************************************** + * ThreadDetach (WAYLAND.@) + */ +static void WAYLAND_ThreadDetach(void) +{ + struct wayland_thread_data *data = wayland_thread_data(); + + if (data) + { + free(data); + /* clear data in case we get re-entered from user32 before the thread is truly dead */ + NtUserGetThreadInfo()->driver_data = 0; + } +} + +static const struct user_driver_funcs waylanddrv_funcs = +{ + .pThreadDetach = WAYLAND_ThreadDetach, +}; + +static const struct user_driver_funcs null_funcs = { 0 }; + static NTSTATUS waylanddrv_unix_init(void *arg) { - if (!wayland_process_init()) return STATUS_UNSUCCESSFUL; + /* Set the user driver functions now so that they are available during + * our initialization. We clear them on error. */ + __wine_set_user_driver(&waylanddrv_funcs, WINE_GDI_DRIVER_VERSION); + + if (!wayland_process_init()) goto err;
return 0; + +err: + __wine_set_user_driver(&null_funcs, WINE_GDI_DRIVER_VERSION); + return STATUS_UNSUCCESSFUL; }
const unixlib_entry_t __wine_unix_call_funcs[] =
From: Alexandros Frantzis alexandros.frantzis@collabora.com
Introduce a thin wrapper around pthread mutex to provide more robust mutex handling and informative error messages in case of suspected deadlock, similarly to ntdll.RtlEnterCriticalSection.
Signed-off-by: Alexandros Frantzis alexandros.frantzis@collabora.com --- dlls/winewayland.drv/Makefile.in | 3 +- dlls/winewayland.drv/wayland_mutex.c | 137 +++++++++++++++++++++++++++ dlls/winewayland.drv/waylanddrv.h | 23 +++++ 3 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 dlls/winewayland.drv/wayland_mutex.c
diff --git a/dlls/winewayland.drv/Makefile.in b/dlls/winewayland.drv/Makefile.in index ba460fcc792..6365ce4845c 100644 --- a/dlls/winewayland.drv/Makefile.in +++ b/dlls/winewayland.drv/Makefile.in @@ -1,11 +1,12 @@ MODULE = winewayland.drv UNIXLIB = winewayland.so UNIX_CFLAGS = $(WAYLAND_CLIENT_CFLAGS) -UNIX_LIBS = -lwin32u $(WAYLAND_CLIENT_LIBS) +UNIX_LIBS = -lwin32u $(WAYLAND_CLIENT_LIBS) $(PTHREAD_LIBS)
C_SRCS = \ dllmain.c \ wayland.c \ + wayland_mutex.c \ waylanddrv_main.c \
RC_SRCS = version.rc diff --git a/dlls/winewayland.drv/wayland_mutex.c b/dlls/winewayland.drv/wayland_mutex.c new file mode 100644 index 00000000000..a32cbbbd519 --- /dev/null +++ b/dlls/winewayland.drv/wayland_mutex.c @@ -0,0 +1,137 @@ +/* + * Wayland mutex + * + * Copyright 2022 Alexandros Frantzis for Collabora Ltd + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#if 0 +#pragma makedep unix +#endif + +#include "config.h" + +#include "waylanddrv.h" + +#include "wine/debug.h" + +#include <errno.h> +#include <time.h> +#include <stdlib.h> +#include <unistd.h> + +WINE_DEFAULT_DEBUG_CHANNEL(waylanddrv); + +/********************************************************************** + * wayland_mutex_init + * + * Initialize a wayland_mutex. + */ +void wayland_mutex_init(struct wayland_mutex *wayland_mutex, int kind, + const char *name) +{ + pthread_mutexattr_t mutexattr; + + pthread_mutexattr_init(&mutexattr); + pthread_mutexattr_settype(&mutexattr, kind); + pthread_mutex_init(&wayland_mutex->mutex, &mutexattr); + pthread_mutexattr_destroy(&mutexattr); + + wayland_mutex->owner_tid = 0; + wayland_mutex->lock_count = 0; + wayland_mutex->name = name; +} + +/********************************************************************** + * wayland_mutex_destroy + * + * Destroys a wayland_mutex. + */ +void wayland_mutex_destroy(struct wayland_mutex *wayland_mutex) +{ + pthread_mutex_destroy(&wayland_mutex->mutex); + wayland_mutex->owner_tid = 0; + wayland_mutex->lock_count = 0; + wayland_mutex->name = NULL; +} + +/********************************************************************** + * wayland_mutex_lock + * + * Lock a mutex, emitting error messages in cases of suspected deadlock. + * In case of an unrecoverable error abort to ensure the program doesn't + * continue with an inconsistent state. + */ +void wayland_mutex_lock(struct wayland_mutex *wayland_mutex) +{ + UINT tid = GetCurrentThreadId(); + struct timespec timeout; + int err; + + clock_gettime(CLOCK_REALTIME, &timeout); + timeout.tv_sec += 5; + + while (TRUE) + { + err = pthread_mutex_timedlock(&wayland_mutex->mutex, &timeout); + if (!err) break; + + if (err == ETIMEDOUT) + { + ERR("mutex %p %s lock timed out in thread %04x, blocked by %04x, retrying (60 sec)\n", + wayland_mutex, wayland_mutex->name, tid, wayland_mutex->owner_tid); + clock_gettime(CLOCK_REALTIME, &timeout); + timeout.tv_sec += 60; + } + else + { + ERR("error locking mutex %p %s errno=%d, aborting\n", + wayland_mutex, wayland_mutex->name, errno); + abort(); + } + } + + wayland_mutex->owner_tid = tid; + wayland_mutex->lock_count++; +} + +/********************************************************************** + * wayland_mutex_unlock + * + * Unlock a mutex. + */ +void wayland_mutex_unlock(struct wayland_mutex *wayland_mutex) +{ + int err; + + wayland_mutex->lock_count--; + + if (wayland_mutex->lock_count == 0) + { + wayland_mutex->owner_tid = 0; + } + else if (wayland_mutex->lock_count < 0) + { + ERR("mutex %p %s lock_count is %d < 0\n", + wayland_mutex, wayland_mutex->name, wayland_mutex->lock_count); + } + + if ((err = pthread_mutex_unlock(&wayland_mutex->mutex))) + { + ERR("failed to unlock mutex %p %s errno=%d\n", + wayland_mutex, wayland_mutex->name, err); + } +} diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 057eb3f8350..6c1cd770a6d 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -25,6 +25,7 @@ # error You must include config.h to use this header #endif
+#include <pthread.h> #include <stdarg.h> #include <wayland-client.h>
@@ -40,6 +41,18 @@
extern struct wl_display *process_wl_display DECLSPEC_HIDDEN;
+/********************************************************************** + * Definitions for wayland types + */ + +struct wayland_mutex +{ + pthread_mutex_t mutex; + UINT owner_tid; + int lock_count; + const char *name; +}; + /********************************************************************** * Wayland thread data */ @@ -61,4 +74,14 @@ static inline struct wayland_thread_data *wayland_thread_data(void)
BOOL wayland_process_init(void) DECLSPEC_HIDDEN;
+/********************************************************************** + * Wayland mutex + */ + +void wayland_mutex_init(struct wayland_mutex *wayland_mutex, int kind, + const char *name) DECLSPEC_HIDDEN; +void wayland_mutex_destroy(struct wayland_mutex *wayland_mutex) DECLSPEC_HIDDEN; +void wayland_mutex_lock(struct wayland_mutex *wayland_mutex) DECLSPEC_HIDDEN; +void wayland_mutex_unlock(struct wayland_mutex *wayland_mutex) DECLSPEC_HIDDEN; + #endif /* __WINE_WAYLANDDRV_H */
From: Alexandros Frantzis alexandros.frantzis@collabora.com
Every thread that requires interaction with Wayland maintains its own independent set of Wayland protocols objects. Events from Wayland protocol objects are dispatched into a thread-specific Wayland event queue.
This design simplifies synchronization, since there is no shared Wayland state between threads, and will later make it easier to dispatch events to the proper thread message queue. The downside is that there is some duplication of event handling if multiple GUI threads are present.
Signed-off-by: Alexandros Frantzis alexandros.frantzis@collabora.com --- dlls/winewayland.drv/wayland.c | 132 +++++++++++++++++++++++++ dlls/winewayland.drv/waylanddrv.h | 27 +++++ dlls/winewayland.drv/waylanddrv_main.c | 10 ++ 3 files changed, 169 insertions(+)
diff --git a/dlls/winewayland.drv/wayland.c b/dlls/winewayland.drv/wayland.c index 9b61427c8aa..852226cbb59 100644 --- a/dlls/winewayland.drv/wayland.c +++ b/dlls/winewayland.drv/wayland.c @@ -26,8 +26,140 @@
#include "waylanddrv.h"
+#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(waylanddrv); + struct wl_display *process_wl_display = NULL;
+static struct wayland_mutex thread_wayland_mutex = +{ + PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, 0, 0, __FILE__ ": thread_wayland_mutex" +}; + +static struct wl_list thread_wayland_list = {&thread_wayland_list, &thread_wayland_list}; + +/********************************************************************** + * Registry handling + */ + +static void registry_handle_global(void *data, struct wl_registry *registry, + uint32_t id, const char *interface, + uint32_t version) +{ + struct wayland *wayland = data; + + TRACE("interface=%s version=%d\n id=%u\n", interface, version, id); + + if (strcmp(interface, "wl_compositor") == 0) + { + wayland->wl_compositor = + wl_registry_bind(registry, id, &wl_compositor_interface, 4); + } +} + +static void registry_handle_global_remove(void *data, struct wl_registry *registry, + uint32_t id) +{ + TRACE("id=%d\n", id); +} + +static const struct wl_registry_listener registry_listener = { + registry_handle_global, + registry_handle_global_remove +}; + +/********************************************************************** + * wayland_init + * + * Initialise a wayland instance. + */ +BOOL wayland_init(struct wayland *wayland) +{ + struct wl_display *wl_display_wrapper; + + TRACE("wayland=%p wl_display=%p\n", wayland, process_wl_display); + + wl_list_init(&wayland->thread_link); + + wayland->process_id = GetCurrentProcessId(); + wayland->thread_id = GetCurrentThreadId(); + wayland->wl_display = process_wl_display; + + if (!wayland->wl_display) + { + ERR("Failed to connect to wayland compositor\n"); + return FALSE; + } + + if (!(wayland->wl_event_queue = wl_display_create_queue(wayland->wl_display))) + { + ERR("Failed to create event queue\n"); + return FALSE; + } + + if (!(wl_display_wrapper = wl_proxy_create_wrapper(wayland->wl_display))) + { + ERR("Failed to create proxy wrapper for wl_display\n"); + return FALSE; + } + wl_proxy_set_queue((struct wl_proxy *) wl_display_wrapper, wayland->wl_event_queue); + + wayland->wl_registry = wl_display_get_registry(wl_display_wrapper); + wl_proxy_wrapper_destroy(wl_display_wrapper); + if (!wayland->wl_registry) + { + ERR("Failed to get to wayland registry\n"); + return FALSE; + } + + /* Populate registry */ + wl_registry_add_listener(wayland->wl_registry, ®istry_listener, wayland); + + /* We need three roundtrips. One to get and bind globals, one to handle all + * initial events produced from registering the globals and one more to + * handle potential third-order registrations. */ + wl_display_roundtrip_queue(wayland->wl_display, wayland->wl_event_queue); + wl_display_roundtrip_queue(wayland->wl_display, wayland->wl_event_queue); + wl_display_roundtrip_queue(wayland->wl_display, wayland->wl_event_queue); + + /* Keep a list of all thread wayland instances. */ + wayland_mutex_lock(&thread_wayland_mutex); + wl_list_insert(&thread_wayland_list, &wayland->thread_link); + wayland_mutex_unlock(&thread_wayland_mutex); + + wayland->initialized = TRUE; + + return TRUE; +} + +/********************************************************************** + * wayland_deinit + * + * Deinitialise a wayland instance, releasing all associated resources. + */ +void wayland_deinit(struct wayland *wayland) +{ + TRACE("%p\n", wayland); + + wayland_mutex_lock(&thread_wayland_mutex); + wl_list_remove(&wayland->thread_link); + wayland_mutex_unlock(&thread_wayland_mutex); + + if (wayland->wl_compositor) + wl_compositor_destroy(wayland->wl_compositor); + + if (wayland->wl_registry) + wl_registry_destroy(wayland->wl_registry); + + if (wayland->wl_event_queue) + wl_event_queue_destroy(wayland->wl_event_queue); + + wl_display_flush(wayland->wl_display); + + memset(wayland, 0, sizeof(*wayland)); +} + /********************************************************************** * wayland_process_init * diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 6c1cd770a6d..ee6ee2589a8 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -53,12 +53,25 @@ struct wayland_mutex const char *name; };
+struct wayland +{ + struct wl_list thread_link; + BOOL initialized; + DWORD process_id; + DWORD thread_id; + struct wl_display *wl_display; + struct wl_event_queue *wl_event_queue; + struct wl_registry *wl_registry; + struct wl_compositor *wl_compositor; +}; + /********************************************************************** * Wayland thread data */
struct wayland_thread_data { + struct wayland wayland; };
extern struct wayland_thread_data *wayland_init_thread_data(void) DECLSPEC_HIDDEN; @@ -68,11 +81,25 @@ static inline struct wayland_thread_data *wayland_thread_data(void) return (struct wayland_thread_data *)(UINT_PTR)NtUserGetThreadInfo()->driver_data; }
+static inline struct wayland *thread_init_wayland(void) +{ + return &wayland_init_thread_data()->wayland; +} + +static inline struct wayland *thread_wayland(void) +{ + struct wayland_thread_data *data = wayland_thread_data(); + if (!data) return NULL; + return &data->wayland; +} + /********************************************************************** * Wayland initialization */
BOOL wayland_process_init(void) DECLSPEC_HIDDEN; +BOOL wayland_init(struct wayland *wayland) DECLSPEC_HIDDEN; +void wayland_deinit(struct wayland *wayland) DECLSPEC_HIDDEN;
/********************************************************************** * Wayland mutex diff --git a/dlls/winewayland.drv/waylanddrv_main.c b/dlls/winewayland.drv/waylanddrv_main.c index 10410157709..787d837cc0b 100644 --- a/dlls/winewayland.drv/waylanddrv_main.c +++ b/dlls/winewayland.drv/waylanddrv_main.c @@ -35,6 +35,7 @@ #include <stdlib.h>
WINE_DEFAULT_DEBUG_CHANNEL(waylanddrv); +WINE_DECLARE_DEBUG_CHANNEL(winediag);
/*********************************************************************** * Initialize per thread data @@ -51,6 +52,14 @@ struct wayland_thread_data *wayland_init_thread_data(void) NtTerminateProcess(0, 1); }
+ if (!wayland_init(&data->wayland)) + { + ERR_(winediag)("waylanddrv: Can't open wayland display. Please ensure " + "that your wayland server is running and that " + "$WAYLAND_DISPLAY is set correctly.\n"); + NtTerminateProcess(0, 1); + } + NtUserGetThreadInfo()->driver_data = (UINT_PTR)data;
return data; @@ -65,6 +74,7 @@ static void WAYLAND_ThreadDetach(void)
if (data) { + wayland_deinit(&data->wayland); free(data); /* clear data in case we get re-entered from user32 before the thread is truly dead */ NtUserGetThreadInfo()->driver_data = 0;
From: Alexandros Frantzis alexandros.frantzis@collabora.com
Having access to the Wayland thread data will allow the desktop process to eventually access information that requires interaction with the Wayland compositor.
Signed-off-by: Alexandros Frantzis alexandros.frantzis@collabora.com --- dlls/winewayland.drv/Makefile.in | 1 + dlls/winewayland.drv/waylanddrv.h | 6 ++++ dlls/winewayland.drv/waylanddrv_main.c | 1 + dlls/winewayland.drv/window.c | 50 ++++++++++++++++++++++++++ 4 files changed, 58 insertions(+) create mode 100644 dlls/winewayland.drv/window.c
diff --git a/dlls/winewayland.drv/Makefile.in b/dlls/winewayland.drv/Makefile.in index 6365ce4845c..627cda9b7d3 100644 --- a/dlls/winewayland.drv/Makefile.in +++ b/dlls/winewayland.drv/Makefile.in @@ -8,5 +8,6 @@ C_SRCS = \ wayland.c \ wayland_mutex.c \ waylanddrv_main.c \ + window.c \
RC_SRCS = version.rc diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index ee6ee2589a8..b9ea28be33c 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -111,4 +111,10 @@ void wayland_mutex_destroy(struct wayland_mutex *wayland_mutex) DECLSPEC_HIDDEN; void wayland_mutex_lock(struct wayland_mutex *wayland_mutex) DECLSPEC_HIDDEN; void wayland_mutex_unlock(struct wayland_mutex *wayland_mutex) DECLSPEC_HIDDEN;
+/********************************************************************** + * USER driver functions + */ + +BOOL WAYLAND_CreateWindow(HWND hwnd) DECLSPEC_HIDDEN; + #endif /* __WINE_WAYLANDDRV_H */ diff --git a/dlls/winewayland.drv/waylanddrv_main.c b/dlls/winewayland.drv/waylanddrv_main.c index 787d837cc0b..f4d2a8b32ac 100644 --- a/dlls/winewayland.drv/waylanddrv_main.c +++ b/dlls/winewayland.drv/waylanddrv_main.c @@ -83,6 +83,7 @@ static void WAYLAND_ThreadDetach(void)
static const struct user_driver_funcs waylanddrv_funcs = { + .pCreateWindow = WAYLAND_CreateWindow, .pThreadDetach = WAYLAND_ThreadDetach, };
diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c new file mode 100644 index 00000000000..002f15157bd --- /dev/null +++ b/dlls/winewayland.drv/window.c @@ -0,0 +1,50 @@ +/* + * Window related functions + * + * Copyright 2020 Alexandros Frantzis for Collabora Ltd + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#if 0 +#pragma makedep unix +#endif + +#include "config.h" + +#include "waylanddrv.h" + +#include "wine/debug.h" + +#include "ntuser.h" + +WINE_DEFAULT_DEBUG_CHANNEL(waylanddrv); + +/********************************************************************** + * WAYLAND_CreateWindow + */ +BOOL WAYLAND_CreateWindow(HWND hwnd) +{ + TRACE("%p\n", hwnd); + + if (hwnd == NtUserGetDesktopWindow()) + { + /* Initialize wayland so that the desktop process has access + * to all the wayland related information (e.g., displays). */ + wayland_init_thread_data(); + } + + return TRUE; +}
From: Alexandros Frantzis alexandros.frantzis@collabora.com
Add the architecture independent pkgconfig path /usr/share/pkgconfig to the PKG_CONFIG_LIBDIR used for 32-bit builds.
Signed-off-by: Alexandros Frantzis alexandros.frantzis@collabora.com --- configure | 2 +- configure.ac | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/configure b/configure index 4d9030e610e..027fe05f418 100755 --- a/configure +++ b/configure @@ -6247,7 +6247,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 diff --git a/configure.ac b/configure.ac index bde4f1a1e24..4f88a5f96c0 100644 --- a/configure.ac +++ b/configure.ac @@ -131,7 +131,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
From: Alexandros Frantzis alexandros.frantzis@collabora.com
Wayland protocol descriptions are distributed as source XML files that need to be transformed to C source and header files with a version of the wayland-scanner tool compatible with the used libwayland library.
This commit enhances the makedep build tool to support building such Wayland protocol XML files. Components can use the WAYLAND_PROTOCOL_SRCS build variable to add protocol XML files to their build.
Signed-off-by: Alexandros Frantzis alexandros.frantzis@collabora.com --- configure | 99 +++++++++++++++++++++++++++++++++++++-- configure.ac | 11 ++++- tools/gitlab/image.docker | 1 + tools/makedep.c | 83 ++++++++++++++++++++++++++++++++ 4 files changed, 189 insertions(+), 5 deletions(-)
diff --git a/configure b/configure index 027fe05f418..2aee02db587 100755 --- a/configure +++ b/configure @@ -702,6 +702,10 @@ INOTIFY_LIBS INOTIFY_CFLAGS PCSCLITE_LIBS PCAP_LIBS +WAYLAND_SCANNER +WAYLAND_PROTOCOLS_DATADIR +WAYLAND_PROTOCOLS_LIBS +WAYLAND_PROTOCOLS_CFLAGS WAYLAND_CLIENT_LIBS WAYLAND_CLIENT_CFLAGS X_EXTRA_LIBS @@ -1750,6 +1754,8 @@ XMKMF CPP WAYLAND_CLIENT_CFLAGS WAYLAND_CLIENT_LIBS +WAYLAND_PROTOCOLS_CFLAGS +WAYLAND_PROTOCOLS_LIBS INOTIFY_CFLAGS INOTIFY_LIBS DBUS_CFLAGS @@ -2554,6 +2560,10 @@ 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_CFLAGS + C compiler flags for wayland-protocols, overriding pkg-config + WAYLAND_PROTOCOLS_LIBS + Linker flags for wayland-protocols, overriding pkg-config INOTIFY_CFLAGS C compiler flags for libinotify, overriding pkg-config INOTIFY_LIBS @@ -15763,13 +15773,92 @@ fi
CPPFLAGS=$ac_save_CPPFLAGS
+ rm -f conftest.err +if ${WAYLAND_PROTOCOLS_CFLAGS:+false} : +then : + if test ${PKG_CONFIG+y} +then : + WAYLAND_PROTOCOLS_CFLAGS=`$PKG_CONFIG --cflags wayland-protocols 2>conftest.err` +fi +fi + +if ${WAYLAND_PROTOCOLS_LIBS:+false} : +then : + if test ${PKG_CONFIG+y} +then : + WAYLAND_PROTOCOLS_LIBS=`$PKG_CONFIG --libs wayland-protocols 2>/dev/null` +fi +fi + + +printf "%s\n" "$as_me:${as_lineno-$LINENO}: wayland-protocols cflags: $WAYLAND_PROTOCOLS_CFLAGS" >&5 +printf "%s\n" "$as_me:${as_lineno-$LINENO}: wayland-protocols libs: $WAYLAND_PROTOCOLS_LIBS" >&5 +if test -s conftest.err; then + printf %s "$as_me:${as_lineno-$LINENO}: wayland-protocols errors: " >&5 + cat conftest.err >&5 +fi +rm -f conftest.err +ac_save_CPPFLAGS=$CPPFLAGS +CPPFLAGS="$CPPFLAGS $WAYLAND_PROTOCOLS_CFLAGS" +WAYLAND_PROTOCOLS_DATADIR=`$PKG_CONFIG --atleast-version=1.14 wayland-protocols && $PKG_CONFIG --variable=pkgdatadir wayland-protocols` + +CPPFLAGS=$ac_save_CPPFLAGS + + # 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="`$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} @@ -23270,6 +23359,10 @@ X_LIBS = $X_LIBS X_EXTRA_LIBS = $X_EXTRA_LIBS WAYLAND_CLIENT_CFLAGS = $WAYLAND_CLIENT_CFLAGS WAYLAND_CLIENT_LIBS = $WAYLAND_CLIENT_LIBS +WAYLAND_PROTOCOLS_CFLAGS = $WAYLAND_PROTOCOLS_CFLAGS +WAYLAND_PROTOCOLS_LIBS = $WAYLAND_PROTOCOLS_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 4f88a5f96c0..7723fce22f1 100644 --- a/configure.ac +++ b/configure.ac @@ -1370,9 +1370,16 @@ else [AC_CHECK_HEADERS([wayland-client.h]) AC_CHECK_LIB(wayland-client,wl_display_connect,[:], [WAYLAND_CLIENT_LIBS=""],[$WAYLAND_CLIENT_LIBS])]) + WINE_PACKAGE_FLAGS(WAYLAND_PROTOCOLS, [wayland-protocols],,,, + [AC_SUBST(WAYLAND_PROTOCOLS_DATADIR, + `$PKG_CONFIG --atleast-version=1.14 wayland-protocols && $PKG_CONFIG --variable=pkgdatadir wayland-protocols`)]) + AC_PATH_PROG(WAYLAND_SCANNER,wayland-scanner, + [`$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/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 \ diff --git a/tools/makedep.c b/tools/makedep.c index b94a221854d..b632cb68978 100644 --- a/tools/makedep.c +++ b/tools/makedep.c @@ -157,6 +157,7 @@ static const char *icotool; static const char *msgfmt; static const char *ln_s; static const char *sed_cmd; +static const char *wayland_scanner; /* per-architecture global variables */ static const char *arch_dirs[MAX_ARCHS]; static const char *arch_pe_dirs[MAX_ARCHS]; @@ -471,6 +472,15 @@ static char *replace_filename( const char *path, const char *name ) return ret; }
+/******************************************************************* + * get_filename + */ +static char *get_filename( const char *name ) +{ + char *filename = strrchr( name, '/' ); + if (!filename) return xstrdup( name ); + return xstrdup( filename + 1 ); +}
/******************************************************************* * replace_substr @@ -1390,6 +1400,35 @@ static struct file *open_src_file( const struct makefile *make, struct incl_file return file; }
+/******************************************************************* + * open_wayland_protocol_file + */ +static struct file *open_wayland_protocol_file( const struct makefile *make, + struct incl_file *pFile ) +{ + char *proto_filename; + struct incl_file *incl_file; + struct file *ret_file = NULL; + + if (!strendswith( pFile->name, "-client-protocol.h" )) return NULL; + + proto_filename = replace_extension( pFile->name, "-client-protocol.h", ".xml" ); + + LIST_FOR_EACH_ENTRY( incl_file, &make->sources, struct incl_file, entry ) + { + if (strendswith( incl_file->name, proto_filename )) + { + pFile->sourcename = incl_file->filename; + pFile->filename = obj_dir_path( make, pFile->name ); + ret_file = incl_file->file; + break; + } + } + + free( proto_filename ); + + return ret_file; +}
/******************************************************************* * find_importlib_module @@ -1429,6 +1468,7 @@ static struct file *open_include_file( const struct makefile *make, struct incl_ if ((file = open_local_generated_file( make, pFile, ".cur", ".svg" ))) return file; if ((file = open_local_generated_file( make, pFile, ".ico", ".svg" ))) return file; } + if ((file = open_wayland_protocol_file( make, pFile ))) return file;
/* check for extra targets */ if (strarray_exists( &make->extra_targets, pFile->name )) @@ -1803,6 +1843,15 @@ static struct makefile *parse_makefile( const char *path ) return make; }
+/******************************************************************* + * is_wayland_protocol + */ +static int is_wayland_protocol( struct incl_file *source ) +{ + return strendswith( source->name, ".xml" ) && + (strstr( source->name, "stable/" ) || strstr( source->name, "unstable/" ) || + strstr( source->name, "staging/" )); +}
/******************************************************************* * add_generated_sources @@ -1916,6 +1965,23 @@ static void add_generated_sources( struct makefile *make ) strarray_addall_uniq( &make->extra_imports, get_expanded_file_local_var( make, obj, "IMPORTS" )); } + if (is_wayland_protocol( source )) + { + char *filename = get_filename( source->name ); + char *code_filename = replace_extension ( filename , ".xml", "-protocol.c" ); + char *header_filename = replace_extension ( filename , ".xml", "-client-protocol.h" ); + + file = add_generated_source( make, code_filename, NULL, 0 ); + file->file->flags |= FLAG_C_UNIX; + file->use_msvcrt = 0; + file = add_generated_source( make, header_filename, NULL, 0 ); + file->file->flags |= FLAG_C_UNIX; + file->use_msvcrt = 0; + + free( filename ); + free( code_filename ); + free( header_filename ); + } } if (make->testdll) { @@ -3125,6 +3191,19 @@ static void output_source_spec( struct makefile *make, struct incl_file *source, } }
+static void output_source_xml( struct makefile *make, struct incl_file *source, const char *obj ) +{ + char *base; + + if (!is_wayland_protocol( source )) return; + + base = get_filename( obj ); + output( "%s-protocol.c: %s\n", obj_dir_path( make, base ), source->filename ); + output( "\t%s%s private-code $< $@\n", cmd_prefix( "WAYLAND_SCANNER" ), wayland_scanner ); + output( "%s-client-protocol.h: %s\n", obj_dir_path( make, base ), source->filename ); + output( "\t%s%s client-header $< $@\n", cmd_prefix( "WAYLAND_SCANNER" ), wayland_scanner); + free( base ); +}
/******************************************************************* * output_source_one_arch @@ -3264,6 +3343,7 @@ static const struct { "in", output_source_in }, { "x", output_source_x }, { "spec", output_source_spec }, + { "xml", output_source_xml }, { NULL, output_source_default } };
@@ -4121,6 +4201,7 @@ static void output_silent_rules(void) "MSG", "SED", "TEST", + "WAYLAND_SCANNER", "WIDL", "WMC", "WRC" @@ -4220,6 +4301,7 @@ static void load_sources( struct makefile *make ) "IN_SRCS", "PO_SRCS", "MANPAGES", + "WAYLAND_PROTOCOL_SRCS", NULL }; const char **var; @@ -4451,6 +4533,7 @@ int main( int argc, char *argv[] ) msgfmt = get_expanded_make_variable( top_makefile, "MSGFMT" ); sed_cmd = get_expanded_make_variable( top_makefile, "SED_CMD" ); ln_s = get_expanded_make_variable( top_makefile, "LN_S" ); + wayland_scanner = get_expanded_make_variable( top_makefile, "WAYLAND_SCANNER" );
if (root_src_dir && !strcmp( root_src_dir, "." )) root_src_dir = NULL; if (tools_dir && !strcmp( tools_dir, "." )) tools_dir = NULL;
Hmm, the pipeline failed because I need a container image with some additional dependencies (see https://gitlab.winehq.org/wine/wine/-/merge_requests/2275/diffs#diff-content...). However, logging in through docker to the container registry fails with a timeout, so I cannot upload a test image (so I can temporarily use it in this MR, to show that everything works). Any ideas?
If building with Wayland support means that X will get prioritized during runtime anyways, doesn't it make sense to always have Wayland built for testing purposes, while the driver is maturing?
I'm looking forward to this, and have a few comments of my own (sorry, forgot to email them! I have a draft somewhere. It mainly involves using libdecor for window decorations, rather than self drawing them).
I think that if Wine has been compiled with wayland support, that is should be opt out at run time. Of course if the user is running pure X11, the application should fallback to that backend instead.
At least to me this makes most sense as people running Wayland would most likely want to use the native backend if it is available. At least to me, opt in is very annoying as most other programs I use are more buggy with Xwayland than with their native Wayland backend. This also ensures that it gets the most testing as early as possible.
This also ensures that it gets the most testing as early as possible.
On the other hand, for users who happen to be running Wayland, it may degrade their experience.
I’m using Sway, and in my experience it’s not uncommon that apps with no stable Wayland support (e.g. Rambox) spuriously no longer start under Wayland even though they used to.
As an avid Wayland user, I’d strongly prefer built-in but opt-in.
On Sun Feb 26 12:46:54 2023 +0000, Claudia Pellegrino wrote:
This also ensures that it gets the most testing as early as possible.
On the other hand, for users who happen to be running Wayland, it may degrade their experience. I’m using Sway, and in my experience it’s not uncommon that apps with no stable Wayland support (e.g. Rambox) spuriously no longer start under Wayland even though they used to. As an avid Wayland user, I’d strongly prefer built-in but opt-in.
Built-in with opt-in sounds best for the initial version. Then once it has a bit of testing in the real world it can be made opt-out.
Jacek Caban (@jacek) commented about configure.ac:
[enable_winex11_drv])
fi
+if test "x$with_wayland" = "xno" +then
- enable_winewayland_drv=no
+fi +WINE_NOTICE_WITH(wayland, [false],
[Wayland ${notice_platform}development files not found, the Wayland driver won't be supported.],
[enable_winewayland_drv])
The usual practice in Wine is to enable all modules unless dependencies are missing or explicitly disabled. I think we can do the same for Wayland driver.
Jacek Caban (@jacek) commented about dlls/winewayland.drv/Makefile.in:
MODULE = winewayland.drv +UNIXLIB = winewayland.so
C_SRCS = \ dllmain.c \
- waylanddrv_main.c \
The usual practice in Wine is to have fewer source files rather than more. I'd suggest merging waylanddrv_main.c and wayland_mutex.c into wayland.c or something along those lines.
Jacek Caban (@jacek) commented about dlls/winewayland.drv/waylanddrv_main.c:
+static const struct user_driver_funcs null_funcs = { 0 };
static NTSTATUS waylanddrv_unix_init(void *arg) {
- if (!wayland_process_init()) return STATUS_UNSUCCESSFUL;
/* Set the user driver functions now so that they are available during
* our initialization. We clear them on error. */
__wine_set_user_driver(&waylanddrv_funcs, WINE_GDI_DRIVER_VERSION);
if (!wayland_process_init()) goto err;
return 0;
+err:
- __wine_set_user_driver(&null_funcs, WINE_GDI_DRIVER_VERSION);
Maybe we should allow passing NULL to `__wine_set_user_driver` and handle that in win32u, which already has `null_user_driver`? For the initial MR, you could also just initialize user driver after `wayland_process_init` call and change that later, when it's needed.
Jacek Caban (@jacek) commented about dlls/winewayland.drv/waylanddrv.h:
BOOL wayland_process_init(void) DECLSPEC_HIDDEN;
+/**********************************************************************
Wayland mutex
- */
+void wayland_mutex_init(struct wayland_mutex *wayland_mutex, int kind,
const char *name) DECLSPEC_HIDDEN;
+void wayland_mutex_destroy(struct wayland_mutex *wayland_mutex) DECLSPEC_HIDDEN; +void wayland_mutex_lock(struct wayland_mutex *wayland_mutex) DECLSPEC_HIDDEN; +void wayland_mutex_unlock(struct wayland_mutex *wayland_mutex) DECLSPEC_HIDDEN;
While patch splitting is generally very much appreciated, introducing (temporary) dead code in the process is discouraged in Wine. An alternative way to split is to introduce those helpers together with a code that uses it, but keep it as a very simple pthread wrappers. Then, in a next commit, you could implement additional robustness checks.
Jacek Caban (@jacek) commented about programs/explorer/desktop.c:
#define DESKTOP_CLASS_ATOM ((LPCWSTR)MAKEINTATOM(32769)) #define DESKTOP_ALL_ACCESS 0x01ff
-static const WCHAR default_driver[] = {'m','a','c',',','x','1','1',0}; +static const WCHAR default_driver[] = {'m','a','c',',','x','1','1',',','w','a','y','l','a','n','d',0};
This feels a bit premature to change defaults now. I think it's fine to do that relatively early, but doing that before driver initialization is in place means that we may end up using it when no Wayland is available. Moving it to the end of this MR would be better, but I'd perhaps suggest doing that once device initialization a bit more complete (maybe after the next planned part, when we have device initialization implemented). Note that it's still possible to use registry to configure the driver meantime.
The last patch looks worrying in terms of forward-compatibility. Looking at your wayland branch, you use a few unstable files. What happens if/when they get promoted to stable? Will those files be moved in wayland-protocols causing your branch to fail to build?
Also, it would be better to have commit adding build system support for protocol files together with at least a simple use of it in the same MR.