fix crash when copy'ing latent plugins
[ardour.git] / libs / ardour / search_paths.cc
1 /*
2     Copyright (C) 2011 Tim Mayberry
3     Copyright (C) 2013 Paul Davis
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19 */
20
21 #include <glib.h>
22 #include <glibmm.h>
23 #include <string.h>
24
25 #include "pbd/pathexpand.h"
26
27 #include "ardour/search_paths.h"
28 #include "ardour/directory_names.h"
29 #include "ardour/filesystem_paths.h"
30
31 #ifdef PLATFORM_WINDOWS
32 #include <windows.h>
33 #include <shlobj.h> // CSIDL_*
34 #include "pbd/windows_special_dirs.h"
35 #endif
36
37 namespace {
38         const char * const backend_env_variable_name = "ARDOUR_BACKEND_PATH";
39         const char * const surfaces_env_variable_name = "ARDOUR_SURFACES_PATH";
40         const char * const export_env_variable_name = "ARDOUR_EXPORT_FORMATS_PATH";
41         const char * const theme_env_variable_name = "ARDOUR_THEMES_PATH";
42         const char * const ladspa_env_variable_name = "LADSPA_PATH";
43         const char * const midi_patch_env_variable_name = "ARDOUR_MIDI_PATCH_PATH";
44         const char * const panner_env_variable_name = "ARDOUR_PANNER_PATH";
45 } // anonymous
46
47 using namespace PBD;
48
49 namespace ARDOUR {
50
51 Searchpath
52 backend_search_path ()
53 {
54         Searchpath spath(user_config_directory ());
55         spath += ardour_dll_directory ();
56         spath.add_subdirectory_to_paths(backend_dir_name);
57
58         spath += Searchpath(Glib::getenv(backend_env_variable_name));
59         return spath;
60 }
61
62 Searchpath
63 control_protocol_search_path ()
64 {
65         Searchpath spath(user_config_directory ());
66         spath += ardour_dll_directory ();
67         spath.add_subdirectory_to_paths (surfaces_dir_name);
68
69         spath += Searchpath(Glib::getenv(surfaces_env_variable_name));
70         return spath;
71 }
72
73 Searchpath
74 theme_search_path ()
75 {
76         Searchpath spath (ardour_data_search_path ());
77         spath.add_subdirectory_to_paths (theme_dir_name);
78
79         spath += Searchpath(Glib::getenv(theme_env_variable_name));
80         return spath;
81 }
82
83 Searchpath
84 export_formats_search_path ()
85 {
86         Searchpath spath (ardour_data_search_path());
87         spath.add_subdirectory_to_paths (export_formats_dir_name);
88
89         bool export_formats_path_defined = false;
90         Searchpath spath_env (Glib::getenv(export_env_variable_name, export_formats_path_defined));
91
92         if (export_formats_path_defined) {
93                 spath += spath_env;
94         }
95
96         return spath;
97 }
98
99 Searchpath
100 ladspa_search_path ()
101 {
102         Searchpath spath_env (Glib::getenv(ladspa_env_variable_name));
103
104         Searchpath spath (user_config_directory ());
105
106         spath += ardour_dll_directory ();
107         spath.add_subdirectory_to_paths (ladspa_dir_name);
108
109 #ifndef PLATFORM_WINDOWS
110         spath.push_back ("/usr/local/lib64/ladspa");
111         spath.push_back ("/usr/local/lib/ladspa");
112         spath.push_back ("/usr/lib64/ladspa");
113         spath.push_back ("/usr/lib/ladspa");
114 #endif
115
116 #ifdef __APPLE__
117         spath.push_back (path_expand ("~/Library/Audio/Plug-Ins/LADSPA"));
118         spath.push_back ("/Library/Audio/Plug-Ins/LADSPA");
119 #endif
120
121         return spath_env + spath;
122 }
123
124 Searchpath
125 lv2_bundled_search_path ()
126 {
127         Searchpath spath( ardour_dll_directory () );
128         spath.add_subdirectory_to_paths ("LV2");
129
130         return spath;
131 }
132
133 Searchpath
134 midi_patch_search_path ()
135 {
136         Searchpath spath (ardour_data_search_path());
137         spath.add_subdirectory_to_paths(midi_patch_dir_name);
138
139         bool midi_patch_path_defined = false;
140         Searchpath spath_env (Glib::getenv(midi_patch_env_variable_name, midi_patch_path_defined));
141
142         if (midi_patch_path_defined) {
143                 spath += spath_env;
144         }
145
146         return spath;
147 }
148
149 Searchpath
150 panner_search_path ()
151 {
152         Searchpath spath(user_config_directory ());
153
154         spath += ardour_dll_directory ();
155         spath.add_subdirectory_to_paths(panner_dir_name);
156         spath += Searchpath(Glib::getenv(panner_env_variable_name));
157
158         return spath;
159 }
160
161 Searchpath
162 template_search_path ()
163 {
164         Searchpath spath (ardour_data_search_path());
165         spath.add_subdirectory_to_paths(templates_dir_name);
166         return spath;
167 }
168
169 Searchpath
170 route_template_search_path ()
171 {
172         Searchpath spath (ardour_data_search_path());
173         spath.add_subdirectory_to_paths(route_templates_dir_name);
174         return spath;
175 }
176
177 Searchpath
178 lua_search_path ()
179 {
180         Searchpath spath (ardour_data_search_path());
181         spath.add_subdirectory_to_paths(lua_dir_name);
182
183         return spath;
184 }
185
186 #ifdef PLATFORM_WINDOWS
187
188 const char*
189 vst_search_path ()
190 {
191         DWORD dwType = REG_SZ;
192         HKEY hKey;
193         DWORD dwSize = PATH_MAX;
194         char* p = 0;
195         char* user_home = 0;
196         char tmp[PATH_MAX+1];
197
198         if (ERROR_SUCCESS == RegOpenKeyExA (HKEY_CURRENT_USER, "Software\\VST", 0, KEY_READ, &hKey)) {
199                 // Look for the user's VST Registry entry
200                 if (ERROR_SUCCESS == RegQueryValueExA (hKey, "VSTPluginsPath", 0, &dwType, (LPBYTE)tmp, &dwSize))
201                         p = g_build_filename (Glib::locale_to_utf8(tmp).c_str(), NULL);
202
203                 RegCloseKey (hKey);
204         }
205
206         if (p == 0) {
207                 if (ERROR_SUCCESS == RegOpenKeyExA (HKEY_LOCAL_MACHINE, "Software\\VST", 0, KEY_READ, &hKey))
208                 {
209                         // Look for a global VST Registry entry
210                         if (ERROR_SUCCESS == RegQueryValueExA (hKey, "VSTPluginsPath", 0, &dwType, (LPBYTE)tmp, &dwSize))
211                                 p = g_build_filename (Glib::locale_to_utf8(tmp).c_str(), NULL);
212
213                         RegCloseKey (hKey);
214                 }
215         }
216
217         if (p == 0) {
218 #if ( (defined __i386__) || (defined _M_IX86) )
219                 char *pVSTx86 = 0;
220                 std::string pProgFilesX86 = PBD::get_win_special_folder_path (CSIDL_PROGRAM_FILESX86);
221
222                 if (!pProgFilesX86.empty()) {
223                         // Look for a VST folder under C:\Program Files (x86)
224                         if ((pVSTx86 = g_build_filename (pProgFilesX86.c_str(), "Steinberg", "VSTPlugins", NULL)))
225                         {
226                                 if (Glib::file_test (pVSTx86, Glib::FILE_TEST_EXISTS))
227                                         if (Glib::file_test (pVSTx86, Glib::FILE_TEST_IS_DIR))
228                                                 p = g_build_filename (pVSTx86, NULL);
229
230                                 g_free (pVSTx86);
231                         }
232                 }
233 #else
234                 // Look for a VST folder under C:\Program Files
235                 char *pVST = 0;
236                 std::string pProgFiles = PBD::get_win_special_folder_path (CSIDL_PROGRAM_FILES);
237
238                 if (!pProgFiles.empty()) {
239                         if ((pVST = g_build_filename (pProgFiles.c_str(), "Steinberg", "VSTPlugins", NULL))) {
240                                 if (Glib::file_test (pVST, Glib::FILE_TEST_EXISTS))
241                                         if (Glib::file_test (pVST, Glib::FILE_TEST_IS_DIR))
242                                                 p = g_build_filename (pVST, NULL);
243
244                                 g_free (pVST);
245                         }
246                 }
247 #endif
248         }
249
250         if (p == 0) {
251                 // If all else failed, assume the plugins are under "My Documents"
252                 user_home = (char*) g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS);
253                 if (user_home) {
254                         p = g_build_filename (user_home, "Plugins", "VST", NULL);
255                 } else {
256                         user_home = g_build_filename(g_get_home_dir(), "My Documents", NULL);
257                         if (user_home)
258                                 p = g_build_filename (user_home, "Plugins", "VST", NULL);
259                 }
260         } else {
261                 // Concatenate the registry path with the user's personal path
262                 user_home = (char*) g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS);
263
264                 if (user_home) {
265                         p = g_build_path (";", p, g_build_filename(user_home, "Plugins", "VST", NULL), NULL);
266                 } else {
267                         user_home = g_build_filename(g_get_home_dir(), "My Documents", NULL);
268
269                         if (user_home) {
270                                 p = g_build_path (";", p, g_build_filename (user_home, "Plugins", "VST", NULL), NULL);
271                         }
272                 }
273         }
274
275         return p;
276 }
277
278 #else
279
280 /* Unix-like. Probably require some OS X specific breakdown if we ever add VST
281  * support on that platform.
282  */
283
284 const char *
285 vst_search_path ()
286 {
287         return "/usr/local/lib/vst:/usr/lib/vst";
288 }
289
290 #endif // PLATFORM_WINDOWS
291
292 } // namespace ARDOUR