[SCM] calf/master: More work on the External UI. Add one-way string port support.

js at users.alioth.debian.org js at users.alioth.debian.org
Tue May 7 15:40:00 UTC 2013


The following commit has been merged in the master branch:
commit 249208e0113d3a550bea21850af496a6cfbb2917
Author: Krzysztof Foltman <wdev at foltman.com>
Date:   Sun Apr 4 00:15:40 2010 +0100

    More work on the External UI. Add one-way string port support.
    
    Get all features and string port ID in the LV2 UI base class. Enable all host
    sends when External UI plugin is instantiated and connected with the
    out-of-process GUI. Send a value to string port on receiving configure
    message via OSC.

diff --git a/src/lv2gui.cpp b/src/lv2gui.cpp
index cf1f905..edcec6d 100644
--- a/src/lv2gui.cpp
+++ b/src/lv2gui.cpp
@@ -56,7 +56,20 @@ struct plugin_proxy_base
     const plugin_metadata_iface *plugin_metadata;
     LV2UI_Write_Function write_function;
     LV2UI_Controller controller;
+
+    // Values extracted from the Features array from the host
+    
+    /// Handle to the plugin instance
+    LV2_Handle instance_handle;
+    /// Data access feature instance
+    LV2_Extension_Data_Feature *data_access;
+    /// URI map feature
+    LV2_URI_Map_Feature *uri_map;
+    /// External UI host feature (must be set when instantiating external UI plugins)
+    lv2_external_ui_host *ext_ui_host;
     
+    /// Instance pointer - usually NULL unless the host supports instance-access extension
+    plugin_ctl_iface *instance;
     /// If true, a given parameter (not port) may be sent to host - it is blocked when the parameter is written to by the host
     vector<bool> sends;
     /// Map of parameter name to parameter index (used for mapping configure values to string ports)
@@ -70,22 +83,39 @@ struct plugin_proxy_base
     /// Mapped URI to string port
     uint32_t string_port_uri;
     
-    plugin_proxy_base(const plugin_metadata_iface *metadata, LV2UI_Write_Function wf, LV2UI_Controller c);
-    
+    plugin_proxy_base(const plugin_metadata_iface *metadata, LV2UI_Write_Function wf, LV2UI_Controller c, const LV2_Feature* const* features);
+
+    /// Send a float value to a control port in the host
     void send_float_to_host(int param_no, float value);
     
+    /// Send a string value to a string port in the host, by name (configure-like mechanism)
+    char *configure(const char *key, const char *value);
+    
     /// Enable sending to host for all ports
     void enable_all_sends();
+    
+    /// Obtain instance pointers
+    void resolve_instance();
+
+    /// Map an URI to an integer value using a given URI map
+    uint32_t map_uri(const char *mapURI, const char *keyURI);
 };
 
-plugin_proxy_base::plugin_proxy_base(const plugin_metadata_iface *metadata, LV2UI_Write_Function wf, LV2UI_Controller c)
+plugin_proxy_base::plugin_proxy_base(const plugin_metadata_iface *metadata, LV2UI_Write_Function wf, LV2UI_Controller c, const LV2_Feature* const* features)
 {
     plugin_metadata = metadata;
+    
     write_function = wf;
     controller = c;
+    
+    instance_handle = NULL;
+    data_access = NULL;
+    ext_ui_host = NULL;
     string_port_uri = 0;
+    
     param_count = metadata->get_param_count();
     param_offset = metadata->get_param_port_offset();
+    
     /// Block all updates until GUI is ready
     sends.resize(param_count, false);
     params.resize(param_count);
@@ -96,6 +126,26 @@ plugin_proxy_base::plugin_proxy_base(const plugin_metadata_iface *metadata, LV2U
         if ((pp->flags & PF_TYPEMASK) < PF_STRING)
             params[i] = pp->def_value;
     }
+    for (int i = 0; features[i]; i++)
+    {
+        if (!strcmp(features[i]->URI, "http://lv2plug.in/ns/ext/instance-access"))
+        {
+            instance_handle = features[i]->data;
+        }
+        else if (!strcmp(features[i]->URI, "http://lv2plug.in/ns/ext/data-access"))
+        {
+            data_access = (LV2_Extension_Data_Feature *)features[i]->data;
+        }
+        else if (!strcmp(features[i]->URI, LV2_URI_MAP_URI))
+        {
+            uri_map = (LV2_URI_Map_Feature *)features[i]->data;
+            string_port_uri = map_uri("http://lv2plug.in/ns/extensions/ui", LV2_STRING_PORT_URI);
+        }
+        else if (!strcmp(features[i]->URI, LV2_EXTERNAL_UI_URI))
+        {
+            ext_ui_host = (lv2_external_ui_host *)features[i]->data;
+        }
+    }
 }
 
 void plugin_proxy_base::send_float_to_host(int param_no, float value)
@@ -107,6 +157,57 @@ void plugin_proxy_base::send_float_to_host(int param_no, float value)
     }
 }
 
+void plugin_proxy_base::resolve_instance()
+{
+    fprintf(stderr, "CALF DEBUG: instance %p data %p\n", instance_handle, data_access);
+    if (instance_handle && data_access)
+    {
+        LV2_Calf_Descriptor *calf = (LV2_Calf_Descriptor *)(*data_access->data_access)("http://foltman.com/ns/calf-plugin-instance");
+        fprintf(stderr, "CALF DEBUG: calf %p cpi %p\n", calf, calf ? calf->get_pci : NULL);
+        if (calf && calf->get_pci)
+            instance = calf->get_pci(instance_handle);
+    }
+}
+
+uint32_t plugin_proxy_base::map_uri(const char *mapURI, const char *keyURI)
+{
+    if (!uri_map)
+        return 0;
+    return uri_map->uri_to_id(uri_map->callback_data, mapURI, keyURI);
+}
+
+
+char *plugin_proxy_base::configure(const char *key, const char *value)
+{
+    map<string, int>::iterator i = params_by_name.find(key);
+    if (i == params_by_name.end())
+    {
+        g_error("configure called for unknown key %s\n", key);
+        g_assert(FALSE);
+        return NULL;
+    }
+    int idx = i->second;
+    if (!sends[idx])
+        return NULL;
+    LV2_String_Data data;
+    data.data = (char *)value;
+    data.len = strlen(value);
+    data.storage = -1; // host doesn't need that
+    data.flags = 0;
+    data.pad = 0;
+    
+    if (string_port_uri)
+    {
+        write_function(controller, idx + param_offset, sizeof(LV2_String_Data), string_port_uri, &data);
+    }
+    else
+    {
+        g_warning("String port not supported - cannot write configure variable %s", key);
+    }
+    
+    return NULL;
+}
+
 void plugin_proxy_base::enable_all_sends()
 {
     sends.clear();
@@ -121,22 +222,15 @@ struct lv2_plugin_proxy: public plugin_ctl_iface, public plugin_metadata_proxy,
 {
     /// Plugin GTK+ GUI object pointer
     plugin_gui *gui;
-    /// Instance pointer - usually NULL unless the host supports instance-access extension
-    plugin_ctl_iface *instance;
     /// Glib source ID for update timer
     int source_id;
-    LV2_Handle instance_handle;
-    LV2_Extension_Data_Feature *data_access;
-    LV2_URI_Map_Feature *uri_map;
     
-    lv2_plugin_proxy(const plugin_metadata_iface *md, LV2UI_Write_Function wf, LV2UI_Controller c)
+    lv2_plugin_proxy(const plugin_metadata_iface *md, LV2UI_Write_Function wf, LV2UI_Controller c, const LV2_Feature* const* f)
     : plugin_metadata_proxy(md)
-    , plugin_proxy_base(md, wf, c)
+    , plugin_proxy_base(md, wf, c, f)
     {
         gui = NULL;
         instance = NULL;
-        instance_handle = NULL;
-        data_access = NULL;
     }
     
     virtual float get_param_value(int param_no) {
@@ -169,27 +263,7 @@ struct lv2_plugin_proxy: public plugin_ctl_iface, public plugin_metadata_proxy,
     
     virtual char *configure(const char *key, const char *value)
     {
-        map<string, int>::iterator i = params_by_name.find(key);
-        if (i == params_by_name.end())
-        {
-            fprintf(stderr, "ERROR: configure called for unknown key %s\n", key);
-            assert(0);
-            return NULL;
-        }
-        int idx = i->second;
-        if (!sends[idx])
-            return NULL;
-        LV2_String_Data data;
-        data.data = (char *)value;
-        data.len = strlen(value);
-        data.storage = -1; // host doesn't need that
-        data.flags = 0;
-        data.pad = 0;
-        
-        if (string_port_uri) {
-            write_function(controller, idx + get_param_port_offset(), sizeof(LV2_String_Data), string_port_uri, &data);
-        }
-        
+        plugin_proxy_base::configure(key, value);
         return NULL;
     }
     
@@ -198,22 +272,6 @@ struct lv2_plugin_proxy: public plugin_ctl_iface, public plugin_metadata_proxy,
     void send_configures(send_configure_iface *sci) { 
         fprintf(stderr, "TODO: send_configures (non-control port configuration dump) not implemented in LV2 GUIs\n");
     }
-    void resolve_instance() {
-        fprintf(stderr, "CALF DEBUG: instance %p data %p\n", instance_handle, data_access);
-        if (instance_handle && data_access)
-        {
-            LV2_Calf_Descriptor *calf = (LV2_Calf_Descriptor *)(*data_access->data_access)("http://foltman.com/ns/calf-plugin-instance");
-            fprintf(stderr, "CALF DEBUG: calf %p cpi %p\n", calf, calf ? calf->get_pci : NULL);
-            if (calf && calf->get_pci)
-                instance = calf->get_pci(instance_handle);
-        }
-    }
-    uint32_t map_uri(const char *mapURI, const char *keyURI)
-    {
-        if (!uri_map)
-            return 0;
-        return uri_map->uri_to_id(uri_map->callback_data, mapURI, keyURI);
-    }
 };
 
 static gboolean plugin_on_idle(void *data)
@@ -234,23 +292,10 @@ LV2UI_Handle gui_instantiate(const struct _LV2UI_Descriptor* descriptor,
     const plugin_metadata_iface *md = plugin_registry::instance().get_by_uri(plugin_uri);
     if (!md)
         return NULL;
-    lv2_plugin_proxy *proxy = new lv2_plugin_proxy(md, write_function, controller);
+    lv2_plugin_proxy *proxy = new lv2_plugin_proxy(md, write_function, controller, features);
     if (!proxy)
         return NULL;
     
-    for (int i = 0; features[i]; i++)
-    {
-        if (!strcmp(features[i]->URI, "http://lv2plug.in/ns/ext/instance-access"))
-            proxy->instance_handle = features[i]->data;
-        else if (!strcmp(features[i]->URI, "http://lv2plug.in/ns/ext/data-access"))
-            proxy->data_access = (LV2_Extension_Data_Feature *)features[i]->data;
-        else if (!strcmp(features[i]->URI, LV2_URI_MAP_URI))
-        {
-            proxy->uri_map = (LV2_URI_Map_Feature *)features[i]->data;
-            proxy->string_port_uri = proxy->map_uri("http://lv2plug.in/ns/extensions/ui", 
-                LV2_STRING_PORT_URI);
-        }
-    }
     proxy->resolve_instance();
 
     gtk_rc_parse(PKGLIBDIR "calf.rc");
@@ -328,8 +373,6 @@ void store_preset(GtkWindow *toplevel, plugin_gui *gui)
 class ext_plugin_gui: public lv2_external_ui, public plugin_proxy_base, public osc_message_sink<osc_strstream>
 {
 public:
-    const LV2_Feature* const* features;
-    lv2_external_ui_host *host;
     GPid child_pid;
     osc_server srv;
     osc_client cli;
@@ -355,10 +398,8 @@ private:
 };
 
 ext_plugin_gui::ext_plugin_gui(const plugin_metadata_iface *metadata, LV2UI_Write_Function wf, LV2UI_Controller c, const LV2_Feature* const* f)
-: plugin_proxy_base(metadata, wf, c)
+: plugin_proxy_base(metadata, wf, c, f)
 {
-    features = f;
-    host = NULL;
     confirmed = false;
     
     show = show_;
@@ -368,15 +409,7 @@ ext_plugin_gui::ext_plugin_gui(const plugin_metadata_iface *metadata, LV2UI_Writ
 
 bool ext_plugin_gui::initialise()
 {
-    for(const LV2_Feature* const* i = features; *i; i++)
-    {
-        if (!strcmp((*i)->URI, LV2_EXTERNAL_UI_URI))
-        {
-            host = (lv2_external_ui_host *)(*i)->data;
-            break;
-        }
-    }
-    if (host == NULL)
+    if (ext_ui_host == NULL)
         return false;
     
     srv.sink = this;
@@ -416,7 +449,7 @@ void ext_plugin_gui::run_impl()
 {
     if (waitpid(child_pid, NULL, WNOHANG) != 0)
     {
-        host->ui_closed(controller);
+        ext_ui_host->ui_closed(controller);
     }
     srv.read_from_socket();
 }
@@ -445,8 +478,7 @@ void ext_plugin_gui::receive_osc_message(std::string address, std::string args,
     {
         string key, value;
         buffer >> key >> value;
-        printf("set key %s to value %s\n", key.c_str(), value.c_str());
-        printf("key index %d\n", params_by_name[key] + plugin_metadata->get_param_port_offset());
+        configure(key.c_str(), value.c_str());
     }
     else
         srv.dump.receive_osc_message(address, args, buffer);
@@ -471,7 +503,7 @@ LV2UI_Handle extgui_instantiate(const struct _LV2UI_Descriptor* descriptor,
         return NULL;
     
     string url = ui->srv.get_url() + "/bridge";
-    const gchar *argv[] = { "./calf_gtk", url.c_str(), "calf.so", plugin_uri, (ui->host->plugin_human_id ? ui->host->plugin_human_id : "Unknown"), NULL };
+    const gchar *argv[] = { "./calf_gtk", url.c_str(), "calf.so", plugin_uri, (ui->ext_ui_host->plugin_human_id ? ui->ext_ui_host->plugin_human_id : "Unknown"), NULL };
     GError *error = NULL;
     if (g_spawn_async(bundle_path, (gchar **)argv, NULL, (GSpawnFlags)G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &ui->child_pid, &error))
     {
@@ -486,6 +518,7 @@ LV2UI_Handle extgui_instantiate(const struct _LV2UI_Descriptor* descriptor,
         if (ui->confirmed)
         {
             *(lv2_external_ui **)widget = ui;
+            ui->enable_all_sends();
             return (LV2UI_Handle)ui;
         }
         else

-- 
calf audio plugins packaging



More information about the pkg-multimedia-commits mailing list