Global settings access for VST
This commit is contained in:
parent
901e053f25
commit
0acbce5274
5 changed files with 247 additions and 13 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
173
vst/SfizzSettings.cpp
Normal 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
16
vst/SfizzSettings.h
Normal 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
38
vst/SfizzSettings.mm
Normal 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
|
||||
Loading…
Add table
Reference in a new issue