From c32824e4523a920c9e541cdc40ebaef47e17da29 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sun, 13 Mar 2016 23:52:48 +0100 Subject: [PATCH] Implement LV2 Inline Display Extension --- libs/ardour/ardour/lv2_plugin.h | 12 ++++++ libs/ardour/ardour/plugin.h | 4 ++ libs/ardour/ardour/rc_configuration_vars.h | 1 + libs/ardour/lv2_plugin.cc | 50 +++++++++++++++++++++- 4 files changed, 66 insertions(+), 1 deletion(-) diff --git a/libs/ardour/ardour/lv2_plugin.h b/libs/ardour/ardour/lv2_plugin.h index aacef82e5b..020cddf34b 100644 --- a/libs/ardour/ardour/lv2_plugin.h +++ b/libs/ardour/ardour/lv2_plugin.h @@ -257,6 +257,10 @@ class LIBARDOUR_API LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee RingBuffer* _to_ui; RingBuffer* _from_ui; +#ifdef LV2_EXTENDED + const LV2_Inline_Display_Interface* _display_interface; +#endif + typedef struct { const void* (*extension_data) (const char* uri); } LV2_DataAccess; @@ -269,6 +273,9 @@ class LIBARDOUR_API LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee LV2_Feature _work_schedule_feature; LV2_Feature _options_feature; LV2_Feature _def_state_feature; +#ifdef LV2_EXTENDED + LV2_Feature _queue_draw_feature; +#endif // Options passed to plugin int32_t _seq_size; @@ -292,6 +299,11 @@ class LIBARDOUR_API LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee void load_supported_properties(PropertyDescriptors& descs); +#ifdef LV2_EXTENDED + bool has_inline_display (); + void* render_inline_display (uint32_t, uint32_t); +#endif + void latency_compute_run (); std::string do_save_preset (std::string); void do_remove_preset (std::string); diff --git a/libs/ardour/ardour/plugin.h b/libs/ardour/ardour/plugin.h index 0bc766c462..17ac4e04d9 100644 --- a/libs/ardour/ardour/plugin.h +++ b/libs/ardour/ardour/plugin.h @@ -111,6 +111,10 @@ class LIBARDOUR_API Plugin : public PBD::StatefulDestructible, public Latent void realtime_locate (); void monitoring_changed (); + virtual bool has_inline_display () { return false; } + virtual void* render_inline_display (uint32_t, uint32_t) { return NULL; } + PBD::Signal0 QueueDraw; + struct PresetRecord { PresetRecord () : valid (false) {} PresetRecord (const std::string& u, const std::string& l, bool s = true) : uri (u), label (l), user (s), valid (true) {} diff --git a/libs/ardour/ardour/rc_configuration_vars.h b/libs/ardour/ardour/rc_configuration_vars.h index 00d44376bb..174cae9bec 100644 --- a/libs/ardour/ardour/rc_configuration_vars.h +++ b/libs/ardour/ardour/rc_configuration_vars.h @@ -238,6 +238,7 @@ CONFIG_VARIABLE (bool, verbose_plugin_scan, "verbose-plugin-scan", true) CONFIG_VARIABLE (int, vst_scan_timeout, "vst-scan-timeout", 600) /* deciseconds, per plugin, <= 0 no timeout */ CONFIG_VARIABLE (bool, discover_audio_units, "discover-audio-units", false) CONFIG_VARIABLE (bool, open_gui_after_adding_plugin, "open-gui-after-adding-plugin", true) +CONFIG_VARIABLE (bool, show_inline_display_by_default, "show-inline-display-by-default,", true) /* custom user plugin paths */ CONFIG_VARIABLE (std::string, plugin_path_vst, "plugin-path-vst", "@default@") diff --git a/libs/ardour/lv2_plugin.cc b/libs/ardour/lv2_plugin.cc index 4af6748c41..8283062f3f 100644 --- a/libs/ardour/lv2_plugin.cc +++ b/libs/ardour/lv2_plugin.cc @@ -216,6 +216,14 @@ work_respond(LV2_Worker_Respond_Handle handle, } } +/* inline display extension */ +static void +queue_draw (LV2_Inline_Display_Handle handle) +{ + LV2Plugin* plugin = (LV2Plugin*)handle; + plugin->QueueDraw(); /* EMIT SIGNAL */ +} + /* log extension */ static int @@ -259,6 +267,9 @@ struct LV2Plugin::Impl { , block_length(0) #ifdef HAVE_LV2_1_2_0 , options(0) +#endif +#ifdef LV2_EXTENDED + , queue_draw(0) #endif {} @@ -284,6 +295,9 @@ struct LV2Plugin::Impl { #ifdef HAVE_LV2_1_2_0 LV2_Options_Option* options; #endif +#ifdef LV2_EXTENDED + LV2_Inline_Display* queue_draw; +#endif }; LV2Plugin::LV2Plugin (AudioEngine& engine, @@ -371,7 +385,7 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate) lilv_node_free(state_uri); lilv_node_free(state_iface_uri); - _features = (LV2_Feature**)calloc(11, sizeof(LV2_Feature*)); + _features = (LV2_Feature**)calloc(12, sizeof(LV2_Feature*)); _features[0] = &_instance_access_feature; _features[1] = &_data_access_feature; _features[2] = &_make_path_feature; @@ -388,6 +402,17 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate) lv2_atom_forge_init(&_impl->forge, _uri_map.urid_map()); lv2_atom_forge_init(&_impl->ui_forge, _uri_map.urid_map()); +#ifdef LV2_EXTENDED + _impl->queue_draw = (LV2_Inline_Display*) + malloc (sizeof(LV2_Inline_Display)); + _impl->queue_draw->handle = this; + _impl->queue_draw->queue_draw = queue_draw; + + _queue_draw_feature.URI = LV2_INLINEDISPLAY__queue_draw; + _queue_draw_feature.data = _impl->queue_draw; + _features[n_features++] = &_queue_draw_feature; +#endif + #ifdef HAVE_LV2_1_2_0 LV2_URID atom_Int = _uri_map.uri_to_id(LV2_ATOM__Int); static const int32_t _min_block_length = 1; // may happen during split-cycles @@ -474,6 +499,11 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate) lilv_node_free(options_iface_uri); #endif +#ifdef LV2_EXTENDED + _display_interface = (const LV2_Inline_Display_Interface*) + extension_data (LV2_INLINEDISPLAY__interface); +#endif + if (lilv_plugin_has_feature(plugin, _world.lv2_inPlaceBroken)) { error << string_compose( _("LV2: \"%1\" cannot be used, since it cannot do inplace processing."), @@ -765,6 +795,9 @@ LV2Plugin::~LV2Plugin () #ifdef HAVE_LV2_1_2_0 free(_impl->options); #endif +#ifdef LV2_EXTENDED + free(_impl->queue_draw); +#endif free(_features); free(_make_path_feature.data); @@ -827,6 +860,21 @@ LV2Plugin::ui_is_resizable () const return !fs_matches && !nrs_matches; } +#ifdef LV2_EXTENDED +bool +LV2Plugin::has_inline_display () { + return _display_interface ? true : false; +} + +void* +LV2Plugin::render_inline_display (uint32_t w, uint32_t h) { + if (_display_interface) { + return _display_interface->render ((void*)_impl->instance->lv2_handle, w, h); + } + return NULL; +} +#endif + string LV2Plugin::unique_id() const {