Wrapper {
}
}
-impl WrapperView {
- pub fn new(inner: Arc>, editor: Arc) -> Box {
- Self::allocate(inner, editor, RwLock::new(None))
- }
-}
-
impl IPluginBase for Wrapper {
unsafe fn initialize(&self, _context: *mut c_void) -> tresult {
// We currently don't need or allow any initialization logic
@@ -974,163 +943,6 @@ impl IAudioProcessor for Wrapper {
}
}
-impl IPlugView for WrapperView {
- #[cfg(all(target_family = "unix", not(target_os = "macos")))]
- unsafe fn is_platform_type_supported(&self, type_: vst3_sys::base::FIDString) -> tresult {
- let type_ = CStr::from_ptr(type_);
- match type_.to_str() {
- Ok(type_) if type_ == VST3_PLATFORM_X11_WINDOW => kResultOk,
- _ => {
- nih_debug_assert_failure!("Invalid window handle type: {:?}", type_);
- kResultFalse
- }
- }
- }
-
- #[cfg(all(target_os = "macos"))]
- unsafe fn is_platform_type_supported(&self, type_: vst3_sys::base::FIDString) -> tresult {
- let type_ = CStr::from_ptr(type_);
- match type_.to_str() {
- Ok(type_) if type_ == VST3_PLATFORM_NSVIEW => kResultOk,
- _ => {
- nih_debug_assert_failure!("Invalid window handle type: {:?}", type_);
- kResultFalse
- }
- }
- }
-
- #[cfg(all(target_os = "windows"))]
- unsafe fn is_platform_type_supported(&self, type_: vst3_sys::base::FIDString) -> tresult {
- let type_ = CStr::from_ptr(type_);
- match type_.to_str() {
- Ok(type_) if type_ == VST3_PLATFORM_HWND => kResultOk,
- _ => {
- nih_debug_assert_failure!("Invalid window handle type: {:?}", type_);
- kResultFalse
- }
- }
- }
-
- unsafe fn attached(&self, parent: *mut c_void, type_: vst3_sys::base::FIDString) -> tresult {
- let mut editor_handle = self.editor_handle.write();
- if editor_handle.is_none() {
- let type_ = CStr::from_ptr(type_);
- let handle = match type_.to_str() {
- #[cfg(all(target_family = "unix", not(target_os = "macos")))]
- Ok(type_) if type_ == VST3_PLATFORM_X11_WINDOW => {
- let mut handle = raw_window_handle::unix::XcbHandle::empty();
- handle.window = parent as usize as u32;
- RawWindowHandle::Xcb(handle)
- }
- #[cfg(all(target_os = "macos"))]
- Ok(type_) if type_ == VST3_PLATFORM_NSVIEW => {
- let mut handle = raw_window_handle::macos::MacOSHandle::empty();
- handle.ns_view = parent;
- RawWindowHandle::MacOS(handle)
- }
- #[cfg(all(target_os = "windows"))]
- Ok(type_) if type_ == VST3_PLATFORM_HWND => {
- let mut handle = raw_window_handle::windows::WindowsHandle::empty();
- handle.hwnd = parent;
- RawWindowHandle::Windows(handle)
- }
- _ => {
- nih_debug_assert_failure!("Unknown window handle type: {:?}", type_);
- return kInvalidArgument;
- }
- };
-
- *editor_handle = Some(
- self.editor
- .spawn(ParentWindowHandle { handle }, self.inner.clone()),
- );
- kResultOk
- } else {
- kResultFalse
- }
- }
-
- unsafe fn removed(&self) -> tresult {
- let mut editor_handle = self.editor_handle.write();
- if editor_handle.is_some() {
- *editor_handle = None;
- kResultOk
- } else {
- kResultFalse
- }
- }
-
- unsafe fn on_wheel(&self, _distance: f32) -> tresult {
- // We'll let the plugin use the OS' input mechamisms because not all DAWs (or very few
- // actually) implement these functions
- kResultOk
- }
-
- unsafe fn on_key_down(
- &self,
- _key: vst3_sys::base::char16,
- _key_code: i16,
- _modifiers: i16,
- ) -> tresult {
- kResultOk
- }
-
- unsafe fn on_key_up(
- &self,
- _key: vst3_sys::base::char16,
- _key_code: i16,
- _modifiers: i16,
- ) -> tresult {
- kResultOk
- }
-
- unsafe fn get_size(&self, size: *mut vst3_sys::gui::ViewRect) -> tresult {
- check_null_ptr!(size);
-
- *size = mem::zeroed();
-
- let (width, height) = self.editor.size();
- let size = &mut *size;
- size.left = 0;
- size.right = width as i32;
- size.top = 0;
- size.bottom = height as i32;
-
- kResultOk
- }
-
- unsafe fn on_size(&self, _new_size: *mut vst3_sys::gui::ViewRect) -> tresult {
- // TODO: Implement resizing
- kResultOk
- }
-
- unsafe fn on_focus(&self, _state: TBool) -> tresult {
- kResultOk
- }
-
- unsafe fn set_frame(&self, _frame: *mut c_void) -> tresult {
- // TODO: Implement resizing. We don't implement that right now, so we also don't need the
- // plug frame.
- kResultOk
- }
-
- unsafe fn can_resize(&self) -> tresult {
- // TODO: Implement resizing
- kResultFalse
- }
-
- unsafe fn check_size_constraint(&self, rect: *mut vst3_sys::gui::ViewRect) -> tresult {
- check_null_ptr!(rect);
-
- // TODO: Add this with the resizing
- if (*rect).right - (*rect).left > 0 && (*rect).bottom - (*rect).top > 0 {
- kResultOk
- } else {
- kResultFalse
- }
- }
-}
-
#[doc(hidden)]
#[VST3(implements(IPluginFactory, IPluginFactory2, IPluginFactory3))]
pub struct Factory {
diff --git a/src/wrapper/vst3/view.rs b/src/wrapper/vst3/view.rs
new file mode 100644
index 00000000..5e3c8af1
--- /dev/null
+++ b/src/wrapper/vst3/view.rs
@@ -0,0 +1,216 @@
+// nih-plug: plugins, but rewritten in Rust
+// Copyright (C) 2022 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 .
+
+use parking_lot::RwLock;
+use raw_window_handle::RawWindowHandle;
+use std::any::Any;
+use std::ffi::{c_void, CStr};
+use std::mem;
+use std::sync::Arc;
+use vst3_sys::base::{kInvalidArgument, kResultFalse, kResultOk, tresult, TBool};
+use vst3_sys::gui::IPlugView;
+use vst3_sys::VST3;
+
+use super::inner::WrapperInner;
+use crate::plugin::{Editor, Plugin};
+use crate::ParentWindowHandle;
+
+// Alias needed for the VST3 attribute macro
+use vst3_sys as vst3_com;
+
+// Window handle type constants missing from vst3-sys
+#[allow(unused)]
+const VST3_PLATFORM_HWND: &str = "HWND";
+#[allow(unused)]
+const VST3_PLATFORM_HIVIEW: &str = "HIView";
+#[allow(unused)]
+const VST3_PLATFORM_NSVIEW: &str = "NSView";
+#[allow(unused)]
+const VST3_PLATFORM_UIVIEW: &str = "UIView";
+#[allow(unused)]
+const VST3_PLATFORM_X11_WINDOW: &str = "X11EmbedWindowID";
+
+/// The plugin's [IPlugView] instance created in [IEditController::create_view] if `P` has an
+/// editor. This is managed separately so the lifetime bounds match up.
+#[VST3(implements(IPlugView))]
+pub(crate) struct WrapperView {
+ inner: Arc>,
+ editor: Arc,
+ editor_handle: RwLock>>,
+}
+
+impl WrapperView {
+ pub fn new(inner: Arc>, editor: Arc) -> Box {
+ Self::allocate(inner, editor, RwLock::new(None))
+ }
+}
+
+impl IPlugView for WrapperView {
+ #[cfg(all(target_family = "unix", not(target_os = "macos")))]
+ unsafe fn is_platform_type_supported(&self, type_: vst3_sys::base::FIDString) -> tresult {
+ let type_ = CStr::from_ptr(type_);
+ match type_.to_str() {
+ Ok(type_) if type_ == VST3_PLATFORM_X11_WINDOW => kResultOk,
+ _ => {
+ nih_debug_assert_failure!("Invalid window handle type: {:?}", type_);
+ kResultFalse
+ }
+ }
+ }
+
+ #[cfg(all(target_os = "macos"))]
+ unsafe fn is_platform_type_supported(&self, type_: vst3_sys::base::FIDString) -> tresult {
+ let type_ = CStr::from_ptr(type_);
+ match type_.to_str() {
+ Ok(type_) if type_ == VST3_PLATFORM_NSVIEW => kResultOk,
+ _ => {
+ nih_debug_assert_failure!("Invalid window handle type: {:?}", type_);
+ kResultFalse
+ }
+ }
+ }
+
+ #[cfg(all(target_os = "windows"))]
+ unsafe fn is_platform_type_supported(&self, type_: vst3_sys::base::FIDString) -> tresult {
+ let type_ = CStr::from_ptr(type_);
+ match type_.to_str() {
+ Ok(type_) if type_ == VST3_PLATFORM_HWND => kResultOk,
+ _ => {
+ nih_debug_assert_failure!("Invalid window handle type: {:?}", type_);
+ kResultFalse
+ }
+ }
+ }
+
+ unsafe fn attached(&self, parent: *mut c_void, type_: vst3_sys::base::FIDString) -> tresult {
+ let mut editor_handle = self.editor_handle.write();
+ if editor_handle.is_none() {
+ let type_ = CStr::from_ptr(type_);
+ let handle = match type_.to_str() {
+ #[cfg(all(target_family = "unix", not(target_os = "macos")))]
+ Ok(type_) if type_ == VST3_PLATFORM_X11_WINDOW => {
+ let mut handle = raw_window_handle::unix::XcbHandle::empty();
+ handle.window = parent as usize as u32;
+ RawWindowHandle::Xcb(handle)
+ }
+ #[cfg(all(target_os = "macos"))]
+ Ok(type_) if type_ == VST3_PLATFORM_NSVIEW => {
+ let mut handle = raw_window_handle::macos::MacOSHandle::empty();
+ handle.ns_view = parent;
+ RawWindowHandle::MacOS(handle)
+ }
+ #[cfg(all(target_os = "windows"))]
+ Ok(type_) if type_ == VST3_PLATFORM_HWND => {
+ let mut handle = raw_window_handle::windows::WindowsHandle::empty();
+ handle.hwnd = parent;
+ RawWindowHandle::Windows(handle)
+ }
+ _ => {
+ nih_debug_assert_failure!("Unknown window handle type: {:?}", type_);
+ return kInvalidArgument;
+ }
+ };
+
+ *editor_handle = Some(
+ self.editor
+ .spawn(ParentWindowHandle { handle }, self.inner.clone()),
+ );
+ kResultOk
+ } else {
+ kResultFalse
+ }
+ }
+
+ unsafe fn removed(&self) -> tresult {
+ let mut editor_handle = self.editor_handle.write();
+ if editor_handle.is_some() {
+ *editor_handle = None;
+ kResultOk
+ } else {
+ kResultFalse
+ }
+ }
+
+ unsafe fn on_wheel(&self, _distance: f32) -> tresult {
+ // We'll let the plugin use the OS' input mechamisms because not all DAWs (or very few
+ // actually) implement these functions
+ kResultOk
+ }
+
+ unsafe fn on_key_down(
+ &self,
+ _key: vst3_sys::base::char16,
+ _key_code: i16,
+ _modifiers: i16,
+ ) -> tresult {
+ kResultOk
+ }
+
+ unsafe fn on_key_up(
+ &self,
+ _key: vst3_sys::base::char16,
+ _key_code: i16,
+ _modifiers: i16,
+ ) -> tresult {
+ kResultOk
+ }
+
+ unsafe fn get_size(&self, size: *mut vst3_sys::gui::ViewRect) -> tresult {
+ check_null_ptr!(size);
+
+ *size = mem::zeroed();
+
+ let (width, height) = self.editor.size();
+ let size = &mut *size;
+ size.left = 0;
+ size.right = width as i32;
+ size.top = 0;
+ size.bottom = height as i32;
+
+ kResultOk
+ }
+
+ unsafe fn on_size(&self, _new_size: *mut vst3_sys::gui::ViewRect) -> tresult {
+ // TODO: Implement resizing
+ kResultOk
+ }
+
+ unsafe fn on_focus(&self, _state: TBool) -> tresult {
+ kResultOk
+ }
+
+ unsafe fn set_frame(&self, _frame: *mut c_void) -> tresult {
+ // TODO: Implement resizing. We don't implement that right now, so we also don't need the
+ // plug frame.
+ kResultOk
+ }
+
+ unsafe fn can_resize(&self) -> tresult {
+ // TODO: Implement resizing
+ kResultFalse
+ }
+
+ unsafe fn check_size_constraint(&self, rect: *mut vst3_sys::gui::ViewRect) -> tresult {
+ check_null_ptr!(rect);
+
+ // TODO: Add this with the resizing
+ if (*rect).right - (*rect).left > 0 && (*rect).bottom - (*rect).top > 0 {
+ kResultOk
+ } else {
+ kResultFalse
+ }
+ }
+}