use crate::*; use std::sync::Arc; #[test] fn test_lv2_ui () { let mut features = []; std::mem::forget(features); //gtk::init().unwrap(); use gtk::prelude::{ApplicationExt, ApplicationExtManual}; let app = gtk::Application::builder().application_id("lol.tek").build(); app.connect_activate(move |app| { let host = Host::new(); let mut plugin = plugin::LV2Plugin::new("file:///home/user/.lv2/Odin2.lv2").unwrap(); //let mut plugin = plugin::LV2Plugin::new("file:///home/user/.lv2/ChowKick.lv2").unwrap(); for ui in plugin.plugin.raw().uis().unwrap().iter() { println!("{:?}", ui.uri()); println!("{:?}", ui.classes()); } let handle = plugin.instance.raw_mut().instance_mut().handle(); let instance_access = crate::bound::LV2_Feature { URI: std::ffi::CString::new("http://lv2plug.in/ns/ext/instance-access").unwrap().into_raw(), data: handle as *mut _ as *mut std::ffi::c_void }; let ui_instance = Arc::new(host.instance( &mut plugin, "http://lv2plug.in/ns/extensions/ui#Gtk3UI", "https://thewavewarden.com/odin2", "https://thewavewarden.com/odin2#ParentUI", "http://lv2plug.in/ns/extensions/ui#X11UI", "/home/user/.lv2/Odin2.lv2/Odin2.so", "/home/user/.lv2/Odin2.lv2/Odin2.so", &features, ).unwrap()); //let instance = Arc::new(host.instance( //&mut plugin, //"http://lv2plug.in/ns/extensions/ui#Gtk3UI", //"http://tytel.org/helm", //"http://tytel.org/helm#ParentUI", //"http://lv2plug.in/ns/extensions/ui#X11UI", //"/home/user/.lv2/Helm.lv2/helm.so", //"/home/user/.lv2/Helm.lv2/helm.so", //&features, //).unwrap()); //let instance = Arc::new(host.instance( //&mut plugin, //"http://lv2plug.in/ns/extensions/ui#Gtk3UI", //"http://github.com/Chowdhury-DSP/ChowKick", //"http://github.com/Chowdhury-DSP/ChowKick:UI", //"http://lv2plug.in/ns/extensions/ui#X11UI", //"/home/user/.lv2/ChowKick.lv2/libChowKick.so", //"/home/user/.lv2/ChowKick.lv2/libChowKick.so", //&features, //).unwrap()); //println!("{:?}", instance.get_widget()); }); app.run(); //self::ui::UI::run(&instance).join(); } mod ui { use std::sync::Arc; use std::thread::{spawn, JoinHandle}; use ::winit::{ application::ApplicationHandler, event::WindowEvent, event_loop::{ActiveEventLoop, ControlFlow, EventLoop}, window::{Window, WindowId}, platform::x11::EventLoopBuilderExtX11 }; use crate::{Host, Instance}; pub struct UI { host: Arc, window: Option } impl UI { pub fn new (host: &Arc) -> Self { Self { host: host.clone(), window: None } } pub fn run (host: &Arc) -> JoinHandle<()> { let mut ui = Self::new(host); spawn(move||{ let event_loop = EventLoop::builder().with_x11().with_any_thread(true).build().unwrap(); event_loop.set_control_flow(ControlFlow::Wait); event_loop.run_app(&mut ui).unwrap() }) } } impl ApplicationHandler for UI { fn resumed (&mut self, event_loop: &ActiveEventLoop) { self.window = Some(event_loop.create_window(Window::default_attributes()).unwrap()); } fn window_event (&mut self, event_loop: &ActiveEventLoop, id: WindowId, event: WindowEvent) { match event { WindowEvent::CloseRequested => { self.window.as_ref().unwrap().set_visible(false); event_loop.exit(); }, WindowEvent::RedrawRequested => { self.window.as_ref().unwrap().request_redraw(); } _ => (), } } } } mod plugin { use std::thread::JoinHandle; use std::sync::Arc; use ::livi::{ World, Instance, Plugin as LiviPlugin, Features, FeaturesBuilder, Port, event::LV2AtomSequence, }; /// A LV2 plugin. pub struct LV2Plugin { pub world: World, pub instance: Instance, pub plugin: LiviPlugin, pub features: Arc, pub port_list: Vec, pub input_buffer: Vec, pub ui_thread: Option>, } impl LV2Plugin { pub fn new (uri: &str) -> Result> { // Get 1st plugin at URI let world = World::with_load_bundle(&uri); let features = FeaturesBuilder { min_block_length: 1, max_block_length: 65536 }; let features = world.build_features(features); let mut plugin = None; #[allow(clippy::never_loop)] for p in world.iter_plugins() { plugin = Some(p); break } if plugin.is_none() { return Err(format!("plugin not found: {uri}").into()) } let plugin = plugin.unwrap(); let err = &format!("init {uri}"); // Instantiate Ok(Self { world, instance: unsafe { plugin .instantiate(features.clone(), 48000.0) .expect(&err) }, port_list: { let mut port_list = vec![]; for port in plugin.ports() { port_list.push(port); } port_list }, plugin, features, input_buffer: Vec::with_capacity(1024), ui_thread: None }) } } }