fix crash when copy'ing latent plugins
[ardour.git] / libs / ardour / lxvst_plugin.cc
index 6e30e0c4436d8457ee0a939b089e762ebf0976a2..3939048ad443e7ceca3ccaebb7227b7db66c6e3b 100644 (file)
 
 */
 
+#include <glibmm/fileutils.h>
+#include <glibmm/miscutils.h>
+
+#include "ardour/filesystem_paths.h"
 #include "ardour/linux_vst_support.h"
 #include "ardour/session.h"
 #include "ardour/lxvst_plugin.h"
 
-#include "i18n.h"
+#include "pbd/i18n.h"
 
 using namespace std;
 using namespace ARDOUR;
 using namespace PBD;
 
-LXVSTPlugin::LXVSTPlugin (AudioEngine& e, Session& session, VSTHandle* h)
+LXVSTPlugin::LXVSTPlugin (AudioEngine& e, Session& session, VSTHandle* h, int unique_id)
        : VSTPlugin (e, session, h)
 {
        /* Instantiate the plugin and return a VSTState* */
 
+       Session::vst_current_loading_id = unique_id;
        if ((_state = vstfx_instantiate (_handle, Session::vst_callback, this)) == 0) {
                throw failed_constructor();
        }
+       Session::vst_current_loading_id = 0;
 
        set_plugin (_state->plugin);
 }
@@ -44,9 +50,12 @@ LXVSTPlugin::LXVSTPlugin (const LXVSTPlugin &other)
 {
        _handle = other._handle;
 
+       Session::vst_current_loading_id = PBD::atoi(other.unique_id());
        if ((_state = vstfx_instantiate (_handle, Session::vst_callback, this)) == 0) {
                throw failed_constructor();
        }
+       Session::vst_current_loading_id = 0;
+
        _plugin = _state->plugin;
 
        // Plugin::setup_controls ();
@@ -57,7 +66,7 @@ LXVSTPlugin::~LXVSTPlugin ()
        vstfx_close (_state);
 }
 
-PluginPtr 
+PluginPtr
 LXVSTPluginInfo::load (Session& session)
 {
        try {
@@ -72,7 +81,7 @@ LXVSTPluginInfo::load (Session& session)
                                error << string_compose(_("LXVST: cannot load module from \"%1\""), path) << endmsg;
                        }
                        else {
-                               plugin.reset (new LXVSTPlugin (session.engine(), session, handle));
+                               plugin.reset (new LXVSTPlugin (session.engine(), session, handle, PBD::atoi(unique_id)));
                        }
                }
                else {
@@ -89,6 +98,70 @@ LXVSTPluginInfo::load (Session& session)
        }
 }
 
+std::vector<Plugin::PresetRecord>
+LXVSTPluginInfo::get_presets (bool user_only) const
+{
+       std::vector<Plugin::PresetRecord> p;
+#ifndef NO_PLUGIN_STATE
+       if (!Config->get_use_lxvst()) {
+               return p;
+       }
+
+       if (!user_only) {
+               // TODO - cache, instantiating the plugin can be heavy
+               /* Built-in presets */
+               VSTHandle* handle = vstfx_load(path.c_str());
+               Session::vst_current_loading_id = atoi (unique_id);
+               AEffect* plugin = handle->main_entry (Session::vst_callback);
+               Session::vst_current_loading_id = 0;
+
+               plugin->dispatcher (plugin, effOpen, 0, 0, 0, 0); // :(
+               int const vst_version = plugin->dispatcher (plugin, effGetVstVersion, 0, 0, NULL, 0);
+
+               for (int i = 0; i < plugin->numPrograms; ++i) {
+                       Plugin::PresetRecord r (string_compose (X_("VST:%1:%2"), unique_id, i), "", false);
+                       if (vst_version >= 2) {
+                               char buf[256];
+                               if (plugin->dispatcher (plugin, 29, i, 0, buf, 0) == 1) {
+                                       r.label = buf;
+                               } else {
+                                       r.label = string_compose (_("Preset %1"), i);
+                               }
+                       } else {
+                               r.label = string_compose (_("Preset %1"), i);
+                       }
+                       p.push_back (r);
+               }
+
+               plugin->dispatcher (plugin, effMainsChanged, 0, 0, 0, 0);
+               plugin->dispatcher (plugin, effClose, 0, 0, 0, 0); // :(
+
+               if (handle->plugincnt) {
+                       handle->plugincnt--;
+               }
+               vstfx_unload (handle);
+       }
+
+       /* user presets */
+       XMLTree* t = new XMLTree;
+       std::string pf = Glib::build_filename (ARDOUR::user_config_directory (), "presets", string_compose ("vst-%1", unique_id));
+       if (Glib::file_test (pf, Glib::FILE_TEST_EXISTS)) {
+               t->set_filename (pf);
+               if (t->read ()) { // TODO read names only. skip parsing the actual data
+                       XMLNode* root = t->root ();
+                       for (XMLNodeList::const_iterator i = root->children().begin(); i != root->children().end(); ++i) {
+                               XMLProperty const * uri = (*i)->property (X_("uri"));
+                               XMLProperty const * label = (*i)->property (X_("label"));
+                               p.push_back (Plugin::PresetRecord (uri->value(), label->value(), true));
+                       }
+               }
+       }
+       delete t;
+#endif
+
+       return p;
+}
+
 LXVSTPluginInfo::LXVSTPluginInfo()
 {
        type = ARDOUR::LXVST;