Chris@1472
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@1472
|
2
|
Chris@1472
|
3 /*
|
Chris@1472
|
4 Sonic Visualiser
|
Chris@1472
|
5 An audio file viewer and annotation editor.
|
Chris@1472
|
6 Centre for Digital Music, Queen Mary, University of London.
|
Chris@1472
|
7
|
Chris@1472
|
8 This program is free software; you can redistribute it and/or
|
Chris@1472
|
9 modify it under the terms of the GNU General Public License as
|
Chris@1472
|
10 published by the Free Software Foundation; either version 2 of the
|
Chris@1472
|
11 License, or (at your option) any later version. See the file
|
Chris@1472
|
12 COPYING included with this distribution for more information.
|
Chris@1472
|
13 */
|
Chris@1472
|
14
|
Chris@1472
|
15 #include "PluginPathSetter.h"
|
Chris@1472
|
16
|
Chris@1472
|
17 #include <vamp-hostsdk/PluginHostAdapter.h>
|
Chris@1472
|
18
|
Chris@1472
|
19 #include "RealTimePluginFactory.h"
|
Chris@1472
|
20 #include "LADSPAPluginFactory.h"
|
Chris@1472
|
21 #include "DSSIPluginFactory.h"
|
Chris@1472
|
22
|
Chris@1472
|
23 #include <QSettings>
|
Chris@1472
|
24 #include <QMutexLocker>
|
Chris@1472
|
25
|
Chris@1480
|
26 #include "system/System.h"
|
Chris@1481
|
27 #include "base/Preferences.h"
|
Chris@1481
|
28 #include "base/HelperExecPath.h"
|
Chris@1480
|
29
|
Chris@1472
|
30 QMutex
|
Chris@1472
|
31 PluginPathSetter::m_mutex;
|
Chris@1472
|
32
|
Chris@1472
|
33 PluginPathSetter::Paths
|
Chris@1472
|
34 PluginPathSetter::m_defaultPaths;
|
Chris@1472
|
35
|
Chris@1472
|
36 PluginPathSetter::Paths
|
Chris@1473
|
37 PluginPathSetter::m_environmentPaths;
|
Chris@1473
|
38
|
Chris@1473
|
39 std::map<QString, QString>
|
Chris@1473
|
40 PluginPathSetter::m_originalEnvValues;
|
Chris@1473
|
41
|
Chris@1481
|
42 PluginPathSetter::TypeKeys
|
Chris@1481
|
43 PluginPathSetter::m_supportedKeys;
|
Chris@1480
|
44
|
Chris@1481
|
45 using namespace std;
|
Chris@1481
|
46
|
Chris@1481
|
47 PluginPathSetter::TypeKeys
|
Chris@1481
|
48 PluginPathSetter::getSupportedKeys()
|
Chris@1481
|
49 {
|
Chris@1481
|
50 QMutexLocker locker(&m_mutex);
|
Chris@1481
|
51
|
Chris@1481
|
52 if (!m_supportedKeys.empty()) {
|
Chris@1481
|
53 return m_supportedKeys;
|
Chris@1481
|
54 }
|
Chris@1481
|
55
|
Chris@1481
|
56 TypeKeys keys;
|
Chris@1481
|
57 keys.push_back({ KnownPlugins::VampPlugin, KnownPlugins::FormatNative });
|
Chris@1481
|
58
|
Chris@1481
|
59 bool inProcess = Preferences::getInstance()->getRunPluginsInProcess();
|
Chris@1481
|
60 HelperExecPath hep(inProcess ?
|
Chris@1481
|
61 HelperExecPath::NativeArchitectureOnly :
|
Chris@1481
|
62 HelperExecPath::AllInstalled);
|
Chris@1481
|
63 auto execs = hep.getHelperExecutables("vamp-plugin-load-checker");
|
Chris@1481
|
64 if (execs.size() > 1) {
|
Chris@1481
|
65 keys.push_back({
|
Chris@1481
|
66 KnownPlugins::VampPlugin, KnownPlugins::FormatNonNative32Bit });
|
Chris@1481
|
67 }
|
Chris@1481
|
68
|
Chris@1481
|
69 keys.push_back({ KnownPlugins::LADSPAPlugin, KnownPlugins::FormatNative });
|
Chris@1481
|
70 keys.push_back({ KnownPlugins::DSSIPlugin, KnownPlugins::FormatNative });
|
Chris@1481
|
71
|
Chris@1481
|
72 m_supportedKeys = keys;
|
Chris@1481
|
73 return keys;
|
Chris@1481
|
74 }
|
Chris@1481
|
75
|
Chris@1481
|
76 // call with mutex held please
|
Chris@1473
|
77 PluginPathSetter::Paths
|
Chris@1481
|
78 PluginPathSetter::getEnvironmentPathsUncached(const TypeKeys &keys)
|
Chris@1472
|
79 {
|
Chris@1472
|
80 Paths paths;
|
Chris@1472
|
81
|
Chris@1481
|
82 for (auto k: keys) {
|
Chris@1472
|
83
|
Chris@1481
|
84 KnownPlugins kp(k.second);
|
Chris@1481
|
85
|
Chris@1481
|
86 auto path = kp.getPathFor(k.first);
|
Chris@1481
|
87 QStringList qPath;
|
Chris@1481
|
88 for (auto s: path) {
|
Chris@1481
|
89 qPath.push_back(QString::fromStdString(s));
|
Chris@1481
|
90 }
|
Chris@1481
|
91
|
Chris@1481
|
92 auto var = kp.getPathEnvironmentVariableFor(k.first);
|
Chris@1481
|
93 QString qVar = QString::fromStdString(var);
|
Chris@1481
|
94
|
Chris@1481
|
95 paths[k] = { qPath, qVar, true };
|
Chris@1472
|
96 }
|
Chris@1472
|
97
|
Chris@1473
|
98 return paths;
|
Chris@1473
|
99 }
|
Chris@1473
|
100
|
Chris@1473
|
101 PluginPathSetter::Paths
|
Chris@1473
|
102 PluginPathSetter::getDefaultPaths()
|
Chris@1473
|
103 {
|
Chris@1481
|
104 TypeKeys keys = getSupportedKeys();
|
Chris@1481
|
105
|
Chris@1473
|
106 QMutexLocker locker(&m_mutex);
|
Chris@1473
|
107
|
Chris@1481
|
108 Paths paths;
|
Chris@1481
|
109
|
Chris@1481
|
110 for (auto k: keys) {
|
Chris@1481
|
111
|
Chris@1481
|
112 KnownPlugins kp(k.second);
|
Chris@1481
|
113
|
Chris@1481
|
114 auto path = kp.getDefaultPathFor(k.first);
|
Chris@1481
|
115 QStringList qPath;
|
Chris@1481
|
116 for (auto s: path) {
|
Chris@1481
|
117 qPath.push_back(QString::fromStdString(s));
|
Chris@1481
|
118 }
|
Chris@1481
|
119
|
Chris@1481
|
120 auto var = kp.getPathEnvironmentVariableFor(k.first);
|
Chris@1481
|
121 QString qVar = QString::fromStdString(var);
|
Chris@1481
|
122
|
Chris@1481
|
123 paths[k] = { qPath, qVar, true };
|
Chris@1473
|
124 }
|
Chris@1473
|
125
|
Chris@1481
|
126 return paths;
|
Chris@1472
|
127 }
|
Chris@1472
|
128
|
Chris@1472
|
129 PluginPathSetter::Paths
|
Chris@1473
|
130 PluginPathSetter::getEnvironmentPaths()
|
Chris@1473
|
131 {
|
Chris@1481
|
132 TypeKeys keys = getSupportedKeys();
|
Chris@1481
|
133
|
Chris@1473
|
134 QMutexLocker locker(&m_mutex);
|
Chris@1473
|
135
|
Chris@1473
|
136 if (!m_environmentPaths.empty()) {
|
Chris@1473
|
137 return m_environmentPaths;
|
Chris@1473
|
138 }
|
Chris@1473
|
139
|
Chris@1481
|
140 m_environmentPaths = getEnvironmentPathsUncached(keys);
|
Chris@1473
|
141 return m_environmentPaths;
|
Chris@1473
|
142 }
|
Chris@1473
|
143
|
Chris@1481
|
144 QString
|
Chris@1481
|
145 PluginPathSetter::getSettingTagFor(TypeKey tk)
|
Chris@1481
|
146 {
|
Chris@1481
|
147 string tag = KnownPlugins(tk.second).getTagFor(tk.first);
|
Chris@1481
|
148 if (tk.second == KnownPlugins::FormatNonNative32Bit) {
|
Chris@1481
|
149 tag += "-32";
|
Chris@1481
|
150 }
|
Chris@1481
|
151 return QString::fromStdString(tag);
|
Chris@1481
|
152 }
|
Chris@1481
|
153
|
Chris@1473
|
154 PluginPathSetter::Paths
|
Chris@1472
|
155 PluginPathSetter::getPaths()
|
Chris@1472
|
156 {
|
Chris@1473
|
157 Paths paths = getEnvironmentPaths();
|
Chris@1472
|
158
|
Chris@1472
|
159 QSettings settings;
|
Chris@1472
|
160 settings.beginGroup("Plugins");
|
Chris@1472
|
161
|
Chris@1472
|
162 for (auto p: paths) {
|
Chris@1472
|
163
|
Chris@1481
|
164 TypeKey tk = p.first;
|
Chris@1481
|
165
|
Chris@1481
|
166 QString settingTag = getSettingTagFor(tk);
|
Chris@1472
|
167
|
Chris@1472
|
168 QStringList directories =
|
Chris@1481
|
169 settings.value(QString("directories-%1").arg(settingTag),
|
Chris@1472
|
170 p.second.directories)
|
Chris@1472
|
171 .toStringList();
|
Chris@1472
|
172 QString envVariable =
|
Chris@1481
|
173 settings.value(QString("env-variable-%1").arg(settingTag),
|
Chris@1472
|
174 p.second.envVariable)
|
Chris@1472
|
175 .toString();
|
Chris@1472
|
176 bool useEnvVariable =
|
Chris@1481
|
177 settings.value(QString("use-env-variable-%1").arg(settingTag),
|
Chris@1472
|
178 p.second.useEnvVariable)
|
Chris@1472
|
179 .toBool();
|
Chris@1480
|
180
|
Chris@1480
|
181 string envVarStr = envVariable.toStdString();
|
Chris@1480
|
182 string currentValue;
|
Chris@1480
|
183 (void)getEnvUtf8(envVarStr, currentValue);
|
Chris@1480
|
184
|
Chris@1480
|
185 if (currentValue != "" && useEnvVariable) {
|
Chris@1480
|
186 directories = QString::fromStdString(currentValue).split(
|
Chris@1472
|
187 #ifdef Q_OS_WIN
|
Chris@1472
|
188 ";"
|
Chris@1472
|
189 #else
|
Chris@1472
|
190 ":"
|
Chris@1472
|
191 #endif
|
Chris@1472
|
192 );
|
Chris@1472
|
193 }
|
Chris@1472
|
194
|
Chris@1481
|
195 paths[tk] = { directories, envVariable, useEnvVariable };
|
Chris@1472
|
196 }
|
Chris@1472
|
197
|
Chris@1472
|
198 settings.endGroup();
|
Chris@1472
|
199
|
Chris@1472
|
200 return paths;
|
Chris@1472
|
201 }
|
Chris@1472
|
202
|
Chris@1472
|
203 void
|
Chris@1472
|
204 PluginPathSetter::savePathSettings(Paths paths)
|
Chris@1472
|
205 {
|
Chris@1472
|
206 QSettings settings;
|
Chris@1472
|
207 settings.beginGroup("Plugins");
|
Chris@1472
|
208
|
Chris@1472
|
209 for (auto p: paths) {
|
Chris@1481
|
210 QString settingTag = getSettingTagFor(p.first);
|
Chris@1481
|
211 settings.setValue(QString("directories-%1").arg(settingTag),
|
Chris@1472
|
212 p.second.directories);
|
Chris@1481
|
213 settings.setValue(QString("env-variable-%1").arg(settingTag),
|
Chris@1472
|
214 p.second.envVariable);
|
Chris@1481
|
215 settings.setValue(QString("use-env-variable-%1").arg(settingTag),
|
Chris@1472
|
216 p.second.useEnvVariable);
|
Chris@1472
|
217 }
|
Chris@1472
|
218
|
Chris@1472
|
219 settings.endGroup();
|
Chris@1472
|
220 }
|
Chris@1472
|
221
|
Chris@1473
|
222 QString
|
Chris@1473
|
223 PluginPathSetter::getOriginalEnvironmentValue(QString envVariable)
|
Chris@1473
|
224 {
|
Chris@1473
|
225 if (m_originalEnvValues.find(envVariable) != m_originalEnvValues.end()) {
|
Chris@1473
|
226 return m_originalEnvValues.at(envVariable);
|
Chris@1473
|
227 } else {
|
Chris@1473
|
228 return QString();
|
Chris@1473
|
229 }
|
Chris@1473
|
230 }
|
Chris@1473
|
231
|
Chris@1472
|
232 void
|
Chris@1473
|
233 PluginPathSetter::initialiseEnvironmentVariables()
|
Chris@1472
|
234 {
|
Chris@1472
|
235 // Set the relevant environment variables from user configuration,
|
Chris@1472
|
236 // so that later lookups through the standard APIs will follow the
|
Chris@1472
|
237 // same paths as we have in the user config
|
Chris@1472
|
238
|
Chris@1472
|
239 // First ensure the default paths have been recorded for later, so
|
Chris@1472
|
240 // we don't erroneously re-read them from the environment
|
Chris@1472
|
241 // variables we've just set
|
Chris@1472
|
242 (void)getDefaultPaths();
|
Chris@1473
|
243 (void)getEnvironmentPaths();
|
Chris@1472
|
244
|
Chris@1472
|
245 Paths paths = getPaths();
|
Chris@1472
|
246
|
Chris@1472
|
247 for (auto p: paths) {
|
Chris@1472
|
248 QString envVariable = p.second.envVariable;
|
Chris@1480
|
249 string envVarStr = envVariable.toStdString();
|
Chris@1481
|
250 string currentValue;
|
Chris@1481
|
251 getEnvUtf8(envVarStr, currentValue);
|
Chris@1481
|
252 m_originalEnvValues[envVariable] = QString::fromStdString(currentValue);
|
Chris@1481
|
253 if (currentValue != "" && p.second.useEnvVariable) {
|
Chris@1472
|
254 // don't override
|
Chris@1482
|
255 SVDEBUG << "PluginPathSetter: for environment variable "
|
Chris@1482
|
256 << envVariable << ", useEnvVariable setting is false; "
|
Chris@1482
|
257 << "leaving current value alone: it is \""
|
Chris@1482
|
258 << currentValue << "\"" << endl;
|
Chris@1472
|
259 continue;
|
Chris@1472
|
260 }
|
Chris@1472
|
261 QString separator =
|
Chris@1472
|
262 #ifdef Q_OS_WIN
|
Chris@1472
|
263 ";"
|
Chris@1472
|
264 #else
|
Chris@1472
|
265 ":"
|
Chris@1472
|
266 #endif
|
Chris@1472
|
267 ;
|
Chris@1472
|
268 QString proposedValue = p.second.directories.join(separator);
|
Chris@1482
|
269 SVDEBUG << "PluginPathSetter: for environment variable "
|
Chris@1482
|
270 << envVariable << ", useEnvVariable setting is true or "
|
Chris@1482
|
271 << "variable is currently unset; "
|
Chris@1482
|
272 << "changing value from \"" << currentValue
|
Chris@1482
|
273 << "\" to setting preference of \"" << proposedValue
|
Chris@1482
|
274 << "\"" << endl;
|
Chris@1480
|
275 putEnvUtf8(envVarStr, proposedValue.toStdString());
|
Chris@1472
|
276 }
|
Chris@1472
|
277 }
|
Chris@1472
|
278
|