diff --git a/src/common/logging/vst3.cpp b/src/common/logging/vst3.cpp index dd55ac0e..541373a1 100644 --- a/src/common/logging/vst3.cpp +++ b/src/common/logging/vst3.cpp @@ -414,6 +414,15 @@ bool Vst3Logger::log_request( }); } +bool Vst3Logger::log_request(bool is_host_vst, + const YaEditController::CreateView& request) { + return log_request_base(is_host_vst, [&](auto& message) { + message << request.instance_id + << ": IEditController::createView(name = " << request.name + << ")"; + }); +} + bool Vst3Logger::log_request(bool is_host_vst, const YaPluginBase::Initialize& request) { return log_request_base(is_host_vst, [&](auto& message) { @@ -661,7 +670,19 @@ void Vst3Logger::log_response( log_response_base(is_host_vst, [&](auto& message) { message << response.result.string(); if (response.result == Steinberg::kResultOk) { - message << ", " << response.value_normalized << std::endl; + message << ", " << response.value_normalized; + } + }); +} + +void Vst3Logger::log_response( + bool is_host_vst, + const YaEditController::CreateViewResponse& response) { + log_response_base(is_host_vst, [&](auto& message) { + if (response.plug_view_args) { + message << ""; + } else { + message << ""; } }); } diff --git a/src/common/logging/vst3.h b/src/common/logging/vst3.h index 2ee16a8f..de5a73d5 100644 --- a/src/common/logging/vst3.h +++ b/src/common/logging/vst3.h @@ -106,6 +106,7 @@ class Vst3Logger { const YaEditController::SetParamNormalized&); bool log_request(bool is_host_vst, const YaEditController::SetComponentHandler&); + bool log_request(bool is_host_vst, const YaEditController::CreateView&); bool log_request(bool is_host_vst, const YaPluginBase::Initialize&); bool log_request(bool is_host_vst, const YaPluginBase::Terminate&); bool log_request(bool is_host_vst, const YaPluginFactory::Construct&); @@ -140,6 +141,8 @@ class Vst3Logger { const YaEditController::GetParamStringByValueResponse&); void log_response(bool is_host_vst, const YaEditController::GetParamValueByStringResponse&); + void log_response(bool is_host_vst, + const YaEditController::CreateViewResponse&); void log_response(bool is_host_vst, const YaPluginFactory::ConstructArgs&); void log_response(bool is_host_vst, const Configuration&); diff --git a/src/common/serialization/vst3.h b/src/common/serialization/vst3.h index 4908cff3..2b1d554d 100644 --- a/src/common/serialization/vst3.h +++ b/src/common/serialization/vst3.h @@ -90,6 +90,7 @@ using ControlRequest = std::variant plug_view_args; + + template + void serialize(S& s) { + s.ext(plug_view_args, bitsery::ext::StdOptional{}); + } + }; + + /** + * Message to pass through a call to `IEditController::createView(name)` to + * the Wine plugin host. + */ + struct CreateView { + using Response = CreateViewResponse; + + native_size_t instance_id; + + std::string name; + + template + void serialize(S& s) { + s.value8b(instance_id); + s.text1b(name, 128); + } + }; + virtual Steinberg::IPlugView* PLUGIN_API createView(Steinberg::FIDString name) override = 0; diff --git a/src/wine-host/bridges/vst3.cpp b/src/wine-host/bridges/vst3.cpp index fe9bf891..a0ce3426 100644 --- a/src/wine-host/bridges/vst3.cpp +++ b/src/wine-host/bridges/vst3.cpp @@ -371,6 +371,25 @@ void Vst3Bridge::run() { object_instances[request.instance_id] .component_handler_proxy); }, + [&](const YaEditController::CreateView& request) + -> YaEditController::CreateView::Response { + object_instances[request.instance_id].plug_view = + Steinberg::owned( + object_instances[request.instance_id] + .edit_controller->createView(request.name.c_str())); + + // We'll create a proxy so the host can call functions on this + // `IPlugView` object + return YaEditController::CreateViewResponse{ + .plug_view_args = + (object_instances[request.instance_id].plug_view + ? std::make_optional< + Vst3PlugViewProxy::ConstructArgs>( + object_instances[request.instance_id] + .plug_view, + request.instance_id) + : std::nullopt)}; + }, [&](YaPluginBase::Initialize& request) -> YaPluginBase::Initialize::Response { // If we got passed a host context, we'll create a proxy object diff --git a/src/wine-host/bridges/vst3.h b/src/wine-host/bridges/vst3.h index ff734630..096899c6 100644 --- a/src/wine-host/bridges/vst3.h +++ b/src/wine-host/bridges/vst3.h @@ -60,6 +60,16 @@ struct InstanceInterfaces { */ Steinberg::IPtr object; + /** + * The `IPlugView` object the plugin returned from a call to + * `IEditController::createView()`. + * + * XXX: Technically VST3 supports multiple named views, so we could have + * multiple different view for a single plugin. This is not used within + * the SDK, so a single pointer should be fine for now. + */ + Steinberg::IPtr plug_view; + // All smart pointers below are created from `component`. They will be null // pointers if `component` did not implement the interface.