From 6f00611892e34ace0bb435868246dce0b4d9c5ce Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Thu, 15 Feb 2024 12:42:24 +0100 Subject: [PATCH] Library Forwarding/wayland: Add functions required by zink + Super Meat Boy on 32-bit --- ThunkLibs/libwayland-client/Guest.cpp | 37 +++++++++++++++++++ ThunkLibs/libwayland-client/Host.cpp | 28 ++++++++++++-- .../libwayland-client_interface.cpp | 10 +++++ 3 files changed, 72 insertions(+), 3 deletions(-) diff --git a/ThunkLibs/libwayland-client/Guest.cpp b/ThunkLibs/libwayland-client/Guest.cpp index 74b0031b7..48514dd17 100644 --- a/ThunkLibs/libwayland-client/Guest.cpp +++ b/ThunkLibs/libwayland-client/Guest.cpp @@ -265,6 +265,38 @@ extern "C" void wl_proxy_marshal(wl_proxy *proxy, uint32_t opcode, ...) { wl_proxy_marshal_array(proxy, opcode, args); } +extern "C" wl_proxy *wl_proxy_marshal_constructor(wl_proxy *proxy, uint32_t opcode, + const wl_interface *interface, ...) { + wl_argument args[WL_CLOSURE_MAX_ARGS]; + va_list ap; + + va_start(ap, interface); + // This is equivalent to reading ((wl_proxy_private*)proxy)->interface->methods[opcode].signature on 64-bit. + // On 32-bit, the data layout differs between host and guest however, so we let the host extract the data. + char signature[64]; + fex_wl_get_method_signature(proxy, opcode, signature); + wl_argument_from_va_list(signature, args, WL_CLOSURE_MAX_ARGS, ap); + va_end(ap); + + return wl_proxy_marshal_array_constructor(proxy, opcode, args, interface); +} + +extern "C" wl_proxy *wl_proxy_marshal_constructor_versioned(wl_proxy *proxy, uint32_t opcode, + const wl_interface *interface, uint32_t version, ...) { + wl_argument args[WL_CLOSURE_MAX_ARGS]; + va_list ap; + + va_start(ap, version); + // This is equivalent to reading ((wl_proxy_private*)proxy)->interface->methods[opcode].signature on 64-bit. + // On 32-bit, the data layout differs between host and guest however, so we let the host extract the data. + char signature[64]; + fex_wl_get_method_signature(proxy, opcode, signature); + wl_argument_from_va_list(signature, args, WL_CLOSURE_MAX_ARGS, ap); + va_end(ap); + + return wl_proxy_marshal_array_constructor_versioned(proxy, opcode, args, interface, version); +} + extern "C" wl_proxy *wl_proxy_marshal_flags(wl_proxy *proxy, uint32_t opcode, const wl_interface *interface, uint32_t version, @@ -289,6 +321,11 @@ extern "C" wl_proxy *wl_proxy_marshal_flags(wl_proxy *proxy, uint32_t opcode, #endif } +extern "C" void wl_log_set_handler_client(wl_log_func_t handler) { + // Ignore +} + + void OnInit() { fex_wl_exchange_interface_pointer(const_cast(&wl_output_interface), "wl_output"); fex_wl_exchange_interface_pointer(const_cast(&wl_shm_pool_interface), "wl_shm_pool"); diff --git a/ThunkLibs/libwayland-client/Host.cpp b/ThunkLibs/libwayland-client/Host.cpp index 9c7618dc2..88c115900 100644 --- a/ThunkLibs/libwayland-client/Host.cpp +++ b/ThunkLibs/libwayland-client/Host.cpp @@ -199,6 +199,7 @@ fex_wl_proxy_marshal_array( wl_proxy *proxy, uint32_t opcode, guest_layout args, guest_layout guest_interface, + bool constructor, // Call the _constructor variant of the native wayland function std::optional version, std::optional flags) { auto interface = lookup_wl_interface(guest_interface); @@ -208,9 +209,9 @@ fex_wl_proxy_marshal_array( auto host_args = fex_wl_remap_argument_list(args, get_proxy_interface(proxy)->methods[opcode]); if (false) { - } else if (!version && !flags) { + } else if (!constructor && !version && !flags) { return nullptr; - } else if (version && flags) { + } else if (!constructor && version && flags) { // wl_proxy_marshal_array_flags is only available starting from Wayland 1.19.91 #if WAYLAND_VERSION_MAJOR * 10000 + WAYLAND_VERSION_MINOR * 100 + WAYLAND_VERSION_MICRO >= 11991 return fexldr_ptr_libwayland_client_wl_proxy_marshal_array_flags(proxy, opcode, interface, version.value(), flags.value(), host_args.data()); @@ -218,19 +219,40 @@ fex_wl_proxy_marshal_array( fprintf(stderr, "Host Wayland version is too old to support FEX thunking\n"); __builtin_trap(); #endif + } else if (constructor && version && !flags) { + return fexldr_ptr_libwayland_client_wl_proxy_marshal_array_constructor_versioned(proxy, opcode, host_args.data(), interface, version.value()); + } else if (constructor && version && !flags) { + return fexldr_ptr_libwayland_client_wl_proxy_marshal_array_constructor(proxy, opcode, host_args.data(), interface); } else { fprintf(stderr, "Invalid configuration\n"); __builtin_trap(); } } +extern "C" wl_proxy* +fexfn_impl_libwayland_client_wl_proxy_marshal_array_constructor_versioned( + wl_proxy *proxy, uint32_t opcode, + guest_layout args, + guest_layout interface, + uint32_t version) { + return fex_wl_proxy_marshal_array(proxy, opcode, args, interface, true, version, std::nullopt); +} + +extern "C" wl_proxy* +fexfn_impl_libwayland_client_wl_proxy_marshal_array_constructor( + wl_proxy *proxy, uint32_t opcode, + guest_layout args, + guest_layout interface) { + return fex_wl_proxy_marshal_array(proxy, opcode, args, interface, true, std::nullopt, std::nullopt); +} + extern "C" wl_proxy* fexfn_impl_libwayland_client_wl_proxy_marshal_array_flags( wl_proxy *proxy, uint32_t opcode, guest_layout interface, uint32_t version, uint32_t flags, guest_layout args) { - return fex_wl_proxy_marshal_array(proxy, opcode, args, interface, version, flags); + return fex_wl_proxy_marshal_array(proxy, opcode, args, interface, false, version, flags); } // Variant of CallbackUnpack::CallGuestPtr that relocates a wl_array parameter diff --git a/ThunkLibs/libwayland-client/libwayland-client_interface.cpp b/ThunkLibs/libwayland-client/libwayland-client_interface.cpp index d47fc1cbd..a38550606 100644 --- a/ThunkLibs/libwayland-client/libwayland-client_interface.cpp +++ b/ThunkLibs/libwayland-client/libwayland-client_interface.cpp @@ -44,11 +44,13 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; @@ -61,6 +63,8 @@ template<> struct fex_gen_param : fexgen::assum template<> struct fex_gen_config : fexgen::custom_host_impl {}; template<> struct fex_gen_param : fexgen::ptr_passthrough {}; template<> struct fex_gen_config {}; +template<> struct fex_gen_config {}; +template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; @@ -73,6 +77,12 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_config : fexgen::custom_host_impl {}; template<> struct fex_gen_param : fexgen::ptr_passthrough {}; +template<> struct fex_gen_config : fexgen::custom_host_impl {}; +template<> struct fex_gen_param : fexgen::ptr_passthrough {}; +template<> struct fex_gen_param : fexgen::ptr_passthrough {}; +template<> struct fex_gen_config : fexgen::custom_host_impl {}; +template<> struct fex_gen_param : fexgen::ptr_passthrough {}; +template<> struct fex_gen_param : fexgen::ptr_passthrough {}; // wl_proxy_marshal_array_flags is only available starting from Wayland 1.19.91 #if WAYLAND_VERSION_MAJOR * 10000 + WAYLAND_VERSION_MINOR * 100 + WAYLAND_VERSION_MICRO >= 11991 template<> struct fex_gen_config : fexgen::custom_host_impl {};