fix crash at session close/exit if a midi-control-surface is used
[ardour.git] / libs / ardour / linux_vst_support.cc
index b134c696806c49acc1cd8dd12f02bb5022bbe534..bd1ed0d27e01946e4da747d6ef10f48f136450a2 100644 (file)
@@ -20,7 +20,6 @@
 #include <stdio.h>
 #include <stdarg.h>
 #include <stdlib.h>
-#include <libgen.h>
 #include <pthread.h>
 #include <signal.h>
 #include <dlfcn.h>
@@ -35,6 +34,7 @@
 #include <glibmm/fileutils.h>
 
 #include "ardour/linux_vst_support.h"
+#include "pbd/basename.h"
 #include "pbd/error.h"
 
 #include "i18n.h"
@@ -112,7 +112,7 @@ vstfx_new ()
 void* vstfx_load_vst_library(const char* path)
 {
        void* dll;
-       char* full_path;
+       char* full_path = NULL;
        char* envdup;
        char* lxvst_path;
        size_t len1;
@@ -152,14 +152,15 @@ void* vstfx_load_vst_library(const char* path)
        len2 = strlen(path);
 
        /*Try all the possibilities in the path - deliminated by : */
-
-       lxvst_path = strtok (envdup, ":");
+       char *saveptr;
+       lxvst_path = strtok_r (envdup, ":", &saveptr);
        
        while (lxvst_path != 0)
        {
                vstfx_error ("\"%s\"", lxvst_path);
                len1 = strlen(lxvst_path);
                
+               if (full_path) free(full_path);
                full_path = (char*)malloc(len1 + 1 + len2 + 1);
                memcpy(full_path, lxvst_path, len1);
                full_path[len1] = '/';
@@ -176,11 +177,11 @@ void* vstfx_load_vst_library(const char* path)
        
                /*Try again*/
 
-               lxvst_path = strtok (0, ":");
+               lxvst_path = strtok_r (0, ":", &saveptr);
        }
 
        /*Free the path*/
-
+       if (full_path) free(full_path);
        free(envdup);
 
        return dll;
@@ -194,14 +195,13 @@ vstfx_load (const char *path)
 {
        char* buf = 0;
        VSTHandle* fhandle;
-       int i;
        
        /*Create a new handle we can use to reference the plugin*/
 
        fhandle = vstfx_handle_new();
        
        /*See if we have .so appended to the path - if not we need to make sure it is added*/
-       
+
        if (strstr (path, ".so") == 0)
        {
 
@@ -210,8 +210,6 @@ vstfx_load (const char *path)
                buf = (char *)malloc(strlen(path) + 4); //The .so and a terminating zero
 
                sprintf (buf, "%s.so", path);
-               
-               fhandle->nameptr = strdup (path);
 
        }
        else
@@ -219,22 +217,14 @@ vstfx_load (const char *path)
                /*We already have .so appened to the filename*/
                
                buf = strdup(path);
-               
-               fhandle->nameptr = strdup (path);
-       }
-       
-       /*Use basename to shorten the path and then strip off the .so - the old VST problem,
-       we don't know anything about its name until we load and instantiate the plugin
-       which we don't want to do at this point*/
-       
-       for(i=0; i < (int)strlen(fhandle->nameptr); i++)
-       {
-               if(fhandle->nameptr[i] == '.')
-                       fhandle->nameptr[i] = 0;
        }
-                       
+
+       /* get a name for the plugin based on the path: ye old VST problem where
+          we don't know anything about its name until we load and instantiate the plugin
+          which we don't want to do at this point
+       */
        
-       fhandle->name = basename (fhandle->nameptr);
+       fhandle->name = strdup (PBD::basename_nosuffix (path).c_str());
 
        /*call load_vstfx_library to actually load the .so into memory*/
 
@@ -249,7 +239,15 @@ vstfx_load (const char *path)
 
        /*Find the main entry point into the plugin*/
 
-       if ((fhandle->main_entry = (main_entry_t) dlsym(fhandle->dll, "main")) == 0)
+       fhandle->main_entry = (main_entry_t) dlsym(fhandle->dll, "main");
+
+       if (fhandle->main_entry == 0) {
+               if ((fhandle->main_entry = (main_entry_t) dlsym(fhandle->dll, "VSTPluginMain")) != 0) {
+                       PBD::warning << path << _(": is a VST >= 2.4 - this plugin may or may not function correctly with this version of Ardour.") << endmsg;
+               }
+       }
+
+       if (fhandle->main_entry == 0)
        {
                /*If it can't be found, unload the plugin and return a 0 handle*/
                
@@ -288,10 +286,9 @@ vstfx_unload (VSTHandle* fhandle)
                fhandle->dll = 0;
        }
 
-       if (fhandle->nameptr)
+       if (fhandle->name)
        {
-               free (fhandle->nameptr);
-               fhandle->name = 0;
+               free (fhandle->name);
        }
        
        /*Don't need the plugin handle any more*/
@@ -309,8 +306,9 @@ vstfx_instantiate (VSTHandle* fhandle, audioMasterCallback amc, void* userptr)
 
        if(fhandle == 0)
        {
-           vstfx_error( "** ERROR ** VSTFX : The handle was 0\n" );
-           return 0;
+               vstfx_error( "** ERROR ** VSTFX : The handle was 0\n" );
+               free (vstfx);
+               return 0;
        }
 
        if ((vstfx->plugin = fhandle->main_entry (amc)) == 0) 
@@ -386,6 +384,7 @@ void vstfx_close (VSTState* vstfx)
                dlclose(vstfx->handle->dll); //dlclose keeps its own reference count
                vstfx->handle->dll = 0;
        }
+       free(vstfx);
 }