Global settings access for VST

This commit is contained in:
Jean Pierre Cimalando 2020-12-09 08:58:04 +01:00
parent 901e053f25
commit 0acbce5274
5 changed files with 247 additions and 13 deletions

View file

@ -19,6 +19,7 @@ set(VSTPLUGIN_SOURCES
SfizzVstState.cpp
SfizzFileScan.cpp
SfizzForeignPaths.cpp
SfizzSettings.cpp
VstPluginFactory.cpp
X11RunLoop.cpp
NativeHelpers.cpp
@ -31,6 +32,7 @@ set(VSTPLUGIN_HEADERS
SfizzVstState.h
SfizzFileScan.h
SfizzForeignPaths.h
SfizzSettings.h
X11RunLoop.h
NativeHelpers.h
FileTrie.h)
@ -38,6 +40,7 @@ set(VSTPLUGIN_HEADERS
if(APPLE)
set(VSTPLUGIN_MAC_SOURCES
SfizzForeignPaths.mm
SfizzSettings.mm
NativeHelpers.mm)
list(APPEND VSTPLUGIN_SOURCES ${VSTPLUGIN_MAC_SOURCES})
set_property(SOURCE ${VSTPLUGIN_MAC_SOURCES} APPEND_STRING
@ -53,7 +56,8 @@ if(WIN32)
endif()
target_link_libraries(${VSTPLUGIN_PRJ_NAME}
PRIVATE ${PROJECT_NAME}::${PROJECT_NAME}
PRIVATE sfizz_editor)
PRIVATE sfizz_editor
PRIVATE sfizz-pugixml)
target_include_directories(${VSTPLUGIN_PRJ_NAME}
PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
set_target_properties(${VSTPLUGIN_PRJ_NAME} PROPERTIES

View file

@ -15,8 +15,6 @@ fs::path getAriaPathSetting(const char* name)
{
fs::path path;
HKEY key = 0;
std::unique_ptr<WCHAR[]> nameW;
unsigned nameSize = MultiByteToWideChar(CP_UTF8, 0, name, -1, nullptr, 0);
if (nameSize == 0)
@ -27,17 +25,22 @@ fs::path getAriaPathSetting(const char* name)
const WCHAR ariaKeyPath[] = L"Software\\Plogue Art et Technologie, Inc\\Aria";
if (RegOpenKeyExW(HKEY_CURRENT_USER, ariaKeyPath, 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS) {
WCHAR valueBuffer[32768 + 1];
DWORD valueSize = sizeof(valueBuffer) - sizeof(WCHAR);
if (RegQueryValueExW(key, nameW.get(), nullptr, nullptr, reinterpret_cast<LPBYTE>(valueBuffer), &valueSize) == ERROR_SUCCESS) {
valueBuffer[32768] = L'\0';
path = fs::path(valueBuffer);
}
RegCloseKey(key);
}
HKEY key = nullptr;
LSTATUS status = RegOpenKeyExW(HKEY_CURRENT_USER, ariaKeyPath, 0, KEY_QUERY_VALUE, &key);
if (status != ERROR_SUCCESS)
return {};
return path;
WCHAR valueW[32768];
DWORD valueSize = sizeof(valueW);
DWORD valueType;
status = RegQueryValueExW(
key, nameW.get(), nullptr,
&valueType, reinterpret_cast<LPBYTE>(valueW), &valueSize);
RegCloseKey(key);
if (status != ERROR_SUCCESS || (valueType != REG_SZ && valueType != REG_EXPAND_SZ))
return {};
return fs::path(valueW);
}
#elif defined(__APPLE__)
// implementation in SfizzForeignPaths.mm

173
vst/SfizzSettings.cpp Normal file
View file

@ -0,0 +1,173 @@
// SPDX-License-Identifier: BSD-2-Clause
// This code is part of the sfizz library and is licensed under a BSD 2-clause
// license. You should have receive a LICENSE.md file along with the code.
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
#include "SfizzSettings.h"
#include <cstdlib>
std::string SfizzSettings::load_or(const char* key, absl::string_view defaultValue)
{
absl::optional<std::string> optValue = load(key);
return optValue ? *optValue : std::string(defaultValue);
}
#if defined(_WIN32)
#include <windows.h>
static HKEY openRegistryKey()
{
LSTATUS status;
HKEY root = HKEY_CURRENT_USER;
HKEY parent = root;
HKEY key = nullptr;
for (const WCHAR* component : {L"Software", L"SFZTools", L"sfizz"}) {
status = RegCreateKeyExW(
parent, component, 0, nullptr,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, nullptr, &key, nullptr);
if (parent != root)
RegCloseKey(parent);
if (status != ERROR_SUCCESS)
return nullptr;
parent = key;
}
return key;
}
static WCHAR* stringToWideChar(const char *str, int strCch = -1)
{
unsigned strSize = MultiByteToWideChar(CP_UTF8, 0, str, strCch, nullptr, 0);
if (strSize == 0)
return {};
std::unique_ptr<WCHAR[]> strW(new WCHAR[strSize]);
if (MultiByteToWideChar(CP_UTF8, 0, str, strCch, strW.get(), strSize) == 0)
return {};
return strW.release();
}
static char* stringToUTF8(const wchar_t *strW, int strWCch = -1)
{
unsigned strSize = WideCharToMultiByte(CP_UTF8, 0, strW, strWCch, nullptr, 0, nullptr, nullptr);
if (strSize == 0)
return {};
std::unique_ptr<char[]> str(new char[strSize]);
if (WideCharToMultiByte(CP_UTF8, 0, strW, strWCch, str.get(), strSize, nullptr, nullptr) == 0)
return {};
return str.release();
}
absl::optional<std::string> SfizzSettings::load(const char* name)
{
std::unique_ptr<WCHAR[]> nameW { stringToWideChar(name) };
if (!nameW)
return {};
HKEY key = openRegistryKey();
if (!key)
return {};
WCHAR valueW[32768];
DWORD valueSize = sizeof(valueW);
DWORD valueType;
LSTATUS status = RegQueryValueExW(
key, nameW.get(), nullptr,
&valueType, reinterpret_cast<BYTE*>(valueW), &valueSize);
RegCloseKey(key);
if (status != ERROR_SUCCESS || (valueType != REG_SZ && valueType != REG_EXPAND_SZ))
return {};
std::unique_ptr<char[]> value { stringToUTF8(valueW) };
if (!value)
return {};
return std::string(value.get());
}
bool SfizzSettings::store(const char* name, absl::string_view value)
{
std::unique_ptr<WCHAR[]> nameW { stringToWideChar(name) };
std::unique_ptr<WCHAR[]> valueW { stringToWideChar(std::string(value).c_str()) };
if (!nameW || !valueW)
return false;
HKEY key = openRegistryKey();
if (!key)
return {};
LSTATUS status = RegSetValueExW(
key, nameW.get(), 0, RRF_RT_REG_SZ,
reinterpret_cast<const BYTE*>(valueW.get()),
(wcslen(valueW.get()) + 1) * sizeof(WCHAR));
RegCloseKey(key);
return status == ERROR_SUCCESS;
}
#elif defined(__APPLE__)
// implementation in SfizzSettings.mm
#else
#include <pugixml.hpp>
#include <ghc/fs_std.hpp>
static const fs::path getSettingsPath()
{
fs::path dirPath;
const char* env;
if ((env = getenv("XDG_CONFIG_HOME")) && env[0] == '/')
dirPath = fs::path(env);
else if ((env = getenv("HOME")) && env[0] == '/')
dirPath = fs::path(env) / ".config";
else
return {};
dirPath /= "SFZTools";
dirPath /= "sfizz";
std::error_code ec;
if (!fs::create_directories(dirPath, ec))
return {};
return dirPath / "settings.xml";
}
absl::optional<std::string> SfizzSettings::load(const char* key)
{
const fs::path path = getSettingsPath();
if (path.empty())
return {};
pugi::xml_document doc;
if (!doc.load_file(path.c_str()))
return {};
pugi::xml_node root = doc.child("properties");
if (!root)
return {};
pugi::xml_node entry = root.find_child_by_attribute("entry", "key", key);
if (!entry)
return {};
return std::string(entry.text().get());
}
bool SfizzSettings::store(const char* key, absl::string_view value)
{
const fs::path path = getSettingsPath();
if (path.empty())
return false;
pugi::xml_document doc;
doc.load_file(path.c_str());
pugi::xml_node root = doc.child("properties");
if (!root)
root = doc.append_child("properties");
pugi::xml_node entry = root.find_child_by_attribute("entry", "key", key);
if (!entry) {
entry = root.append_child("entry");
entry.append_attribute("key").set_value(key);
}
entry.text().set(std::string(value).c_str());
return doc.save_file(path.c_str());
}
#endif

16
vst/SfizzSettings.h Normal file
View file

@ -0,0 +1,16 @@
// SPDX-License-Identifier: BSD-2-Clause
// This code is part of the sfizz library and is licensed under a BSD 2-clause
// license. You should have receive a LICENSE.md file along with the code.
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
#pragma once
#include <absl/strings/string_view.h>
#include <absl/types/optional.h>
class SfizzSettings {
public:
absl::optional<std::string> load(const char* key);
std::string load_or(const char* key, absl::string_view defaultValue);
bool store(const char* key, absl::string_view value);
};

38
vst/SfizzSettings.mm Normal file
View file

@ -0,0 +1,38 @@
// SPDX-License-Identifier: BSD-2-Clause
// This code is part of the sfizz library and is licensed under a BSD 2-clause
// license. You should have receive a LICENSE.md file along with the code.
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
#include "SfizzSettings.h"
#if defined(__APPLE__)
#import <Foundation/Foundation.h>
#if !__has_feature(objc_arc)
#error This source file requires ARC
#endif
static NSUserDefaults* getUserDefaults()
{
return [[NSUserDefaults alloc] initWithSuiteName:@"tools.sfz.sfizz"];;
}
absl::optional<std::string> SfizzSettings::load(const char* key)
{
NSUserDefaults* ud = getUserDefaults();
NSString* value = [ud stringForKey:[NSString stringWithUTF8String:key]];
if (!value)
return {};
return std::string(value.UTF8String);
}
bool SfizzSettings::store(const char* key, absl::string_view value)
{
NSUserDefaults* ud = getUserDefaults();
NSString* object =
[[NSString alloc] initWithBytes:value.data()
length:(NSUInteger)value.size() encoding:NSUTF8StringEncoding];
[ud setObject:object forKey:[NSString stringWithUTF8String:key]];
return true;
}
#endif