fix crash when copy'ing latent plugins
[ardour.git] / libs / ardour / search_paths.cc
index 45a2e13974ef115d56b0ab011944923674104202..96df905eda4315eb2fe1ee2d271f26b905bfded5 100644 (file)
@@ -1,6 +1,6 @@
 /*
-    Copyright (C) 2011 Tim Mayberry 
-    Copyright (C) 2013 Paul Davis 
+    Copyright (C) 2011 Tim Mayberry
+    Copyright (C) 2013 Paul Davis
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -18,7 +18,9 @@
 
 */
 
-#include <glibmm/miscutils.h>
+#include <glib.h>
+#include <glibmm.h>
+#include <string.h>
 
 #include "pbd/pathexpand.h"
 
 #include "ardour/directory_names.h"
 #include "ardour/filesystem_paths.h"
 
+#ifdef PLATFORM_WINDOWS
+#include <windows.h>
+#include <shlobj.h> // CSIDL_*
+#include "pbd/windows_special_dirs.h"
+#endif
+
 namespace {
        const char * const backend_env_variable_name = "ARDOUR_BACKEND_PATH";
        const char * const surfaces_env_variable_name = "ARDOUR_SURFACES_PATH";
        const char * const export_env_variable_name = "ARDOUR_EXPORT_FORMATS_PATH";
+       const char * const theme_env_variable_name = "ARDOUR_THEMES_PATH";
        const char * const ladspa_env_variable_name = "LADSPA_PATH";
+       const char * const midi_patch_env_variable_name = "ARDOUR_MIDI_PATCH_PATH";
+       const char * const panner_env_variable_name = "ARDOUR_PANNER_PATH";
 } // anonymous
 
 using namespace PBD;
@@ -54,11 +65,21 @@ control_protocol_search_path ()
        Searchpath spath(user_config_directory ());
        spath += ardour_dll_directory ();
        spath.add_subdirectory_to_paths (surfaces_dir_name);
-       
+
        spath += Searchpath(Glib::getenv(surfaces_env_variable_name));
        return spath;
 }
 
+Searchpath
+theme_search_path ()
+{
+       Searchpath spath (ardour_data_search_path ());
+       spath.add_subdirectory_to_paths (theme_dir_name);
+
+       spath += Searchpath(Glib::getenv(theme_env_variable_name));
+       return spath;
+}
+
 Searchpath
 export_formats_search_path ()
 {
@@ -100,4 +121,172 @@ ladspa_search_path ()
        return spath_env + spath;
 }
 
+Searchpath
+lv2_bundled_search_path ()
+{
+       Searchpath spath( ardour_dll_directory () );
+       spath.add_subdirectory_to_paths ("LV2");
+
+       return spath;
+}
+
+Searchpath
+midi_patch_search_path ()
+{
+       Searchpath spath (ardour_data_search_path());
+       spath.add_subdirectory_to_paths(midi_patch_dir_name);
+
+       bool midi_patch_path_defined = false;
+       Searchpath spath_env (Glib::getenv(midi_patch_env_variable_name, midi_patch_path_defined));
+
+       if (midi_patch_path_defined) {
+               spath += spath_env;
+       }
+
+       return spath;
+}
+
+Searchpath
+panner_search_path ()
+{
+       Searchpath spath(user_config_directory ());
+
+       spath += ardour_dll_directory ();
+       spath.add_subdirectory_to_paths(panner_dir_name);
+       spath += Searchpath(Glib::getenv(panner_env_variable_name));
+
+       return spath;
+}
+
+Searchpath
+template_search_path ()
+{
+       Searchpath spath (ardour_data_search_path());
+       spath.add_subdirectory_to_paths(templates_dir_name);
+       return spath;
+}
+
+Searchpath
+route_template_search_path ()
+{
+       Searchpath spath (ardour_data_search_path());
+       spath.add_subdirectory_to_paths(route_templates_dir_name);
+       return spath;
+}
+
+Searchpath
+lua_search_path ()
+{
+       Searchpath spath (ardour_data_search_path());
+       spath.add_subdirectory_to_paths(lua_dir_name);
+
+       return spath;
+}
+
+#ifdef PLATFORM_WINDOWS
+
+const char*
+vst_search_path ()
+{
+       DWORD dwType = REG_SZ;
+       HKEY hKey;
+       DWORD dwSize = PATH_MAX;
+       char* p = 0;
+       char* user_home = 0;
+       char tmp[PATH_MAX+1];
+
+       if (ERROR_SUCCESS == RegOpenKeyExA (HKEY_CURRENT_USER, "Software\\VST", 0, KEY_READ, &hKey)) {
+               // Look for the user's VST Registry entry
+               if (ERROR_SUCCESS == RegQueryValueExA (hKey, "VSTPluginsPath", 0, &dwType, (LPBYTE)tmp, &dwSize))
+                       p = g_build_filename (Glib::locale_to_utf8(tmp).c_str(), NULL);
+
+               RegCloseKey (hKey);
+       }
+
+       if (p == 0) {
+               if (ERROR_SUCCESS == RegOpenKeyExA (HKEY_LOCAL_MACHINE, "Software\\VST", 0, KEY_READ, &hKey))
+               {
+                       // Look for a global VST Registry entry
+                       if (ERROR_SUCCESS == RegQueryValueExA (hKey, "VSTPluginsPath", 0, &dwType, (LPBYTE)tmp, &dwSize))
+                               p = g_build_filename (Glib::locale_to_utf8(tmp).c_str(), NULL);
+
+                       RegCloseKey (hKey);
+               }
+       }
+
+       if (p == 0) {
+#if ( (defined __i386__) || (defined _M_IX86) )
+               char *pVSTx86 = 0;
+               std::string pProgFilesX86 = PBD::get_win_special_folder_path (CSIDL_PROGRAM_FILESX86);
+
+               if (!pProgFilesX86.empty()) {
+                       // Look for a VST folder under C:\Program Files (x86)
+                       if ((pVSTx86 = g_build_filename (pProgFilesX86.c_str(), "Steinberg", "VSTPlugins", NULL)))
+                       {
+                               if (Glib::file_test (pVSTx86, Glib::FILE_TEST_EXISTS))
+                                       if (Glib::file_test (pVSTx86, Glib::FILE_TEST_IS_DIR))
+                                               p = g_build_filename (pVSTx86, NULL);
+
+                               g_free (pVSTx86);
+                       }
+               }
+#else
+               // Look for a VST folder under C:\Program Files
+               char *pVST = 0;
+               std::string pProgFiles = PBD::get_win_special_folder_path (CSIDL_PROGRAM_FILES);
+
+               if (!pProgFiles.empty()) {
+                       if ((pVST = g_build_filename (pProgFiles.c_str(), "Steinberg", "VSTPlugins", NULL))) {
+                               if (Glib::file_test (pVST, Glib::FILE_TEST_EXISTS))
+                                       if (Glib::file_test (pVST, Glib::FILE_TEST_IS_DIR))
+                                               p = g_build_filename (pVST, NULL);
+
+                               g_free (pVST);
+                       }
+               }
+#endif
+       }
+
+       if (p == 0) {
+               // If all else failed, assume the plugins are under "My Documents"
+               user_home = (char*) g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS);
+               if (user_home) {
+                       p = g_build_filename (user_home, "Plugins", "VST", NULL);
+               } else {
+                       user_home = g_build_filename(g_get_home_dir(), "My Documents", NULL);
+                       if (user_home)
+                               p = g_build_filename (user_home, "Plugins", "VST", NULL);
+               }
+       } else {
+               // Concatenate the registry path with the user's personal path
+               user_home = (char*) g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS);
+
+               if (user_home) {
+                       p = g_build_path (";", p, g_build_filename(user_home, "Plugins", "VST", NULL), NULL);
+               } else {
+                       user_home = g_build_filename(g_get_home_dir(), "My Documents", NULL);
+
+                       if (user_home) {
+                               p = g_build_path (";", p, g_build_filename (user_home, "Plugins", "VST", NULL), NULL);
+                       }
+               }
+       }
+
+       return p;
+}
+
+#else
+
+/* Unix-like. Probably require some OS X specific breakdown if we ever add VST
+ * support on that platform.
+ */
+
+const char *
+vst_search_path ()
+{
+       return "/usr/local/lib/vst:/usr/lib/vst";
+}
+
+#endif // PLATFORM_WINDOWS
+
 } // namespace ARDOUR