// yabridge: a Wine VST bridge // Copyright (C) 2020 Robbert van der Helm // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program 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 General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include #include #include #include // The plugin should always be compiled to a 64-bit version, but the host // application can also be 32-bit to allow using 32-bit legacy Windows VST in a // modern Linux VST host. Because of this we have to make sure to always use // 64-bit integers in places where we would otherwise use `size_t` and // `intptr_t`. Otherwise the binary serialization would break. The 64 <-> 32 bit // conversion for the 32-bit host application won't cause any issues for us // since we can't directly pass pointers between the plugin and the host anyway. #ifndef __WINE__ // Sanity check for the plugin, both the 64 and 32 bit hosts should follow these // conventions static_assert(std::is_same_v); static_assert(std::is_same_v); #endif using native_size_t = uint64_t; using native_intptr_t = int64_t; // The cannonical overloading template for `std::visitor`, not sure why this // isn't part of the standard library template struct overload : Ts... { using Ts::operator()...; }; template overload(Ts...) -> overload; /** * An object containing the startup options for hosting a plugin in a plugin * group process. These are the exact same options that would have been passed * to `yabridge-host.exe` were the plugin to be hosted individually. */ struct GroupRequest { std::string plugin_path; std::string endpoint_base_dir; template void serialize(S& s) { s.text1b(plugin_path, 4096); s.text1b(endpoint_base_dir, 4096); } }; template <> struct std::hash { std::size_t operator()(GroupRequest const& params) const noexcept { std::hash hasher{}; return hasher(params.plugin_path) ^ (hasher(params.endpoint_base_dir) << 1); } }; /** * The response sent back after the group host process receives a `GroupRequest` * object. This only holds the group process's PID because we need to know if * the group process crashes while it is initializing the plugin to prevent us * from waiting indefinitely for the socket to be connected to. */ struct GroupResponse { pid_t pid; template void serialize(S& s) { s.value4b(pid); } };