@@ -10,6 +10,9 @@ namespace rack { | |||||
namespace string { | namespace string { | ||||
/** Converts a UTF-16/32 string (depending on the size of wchar_t) to a UTF-8 string. */ | |||||
std::string fromWstring(const std::wstring &s); | |||||
std::wstring toWstring(const std::string &s); | |||||
/** Converts a `printf()` format string and optional arguments into a std::string | /** Converts a `printf()` format string and optional arguments into a std::string | ||||
Remember that "%s" must reference a `char *`, so use `.c_str()` for `std::string`s. | Remember that "%s" must reference a `char *`, so use `.c_str()` for `std::string`s. | ||||
*/ | */ | ||||
@@ -1,6 +1,7 @@ | |||||
#include "asset.hpp" | #include "asset.hpp" | ||||
#include "system.hpp" | #include "system.hpp" | ||||
#include "settings.hpp" | #include "settings.hpp" | ||||
#include "string.hpp" | |||||
#include "plugin/Plugin.hpp" | #include "plugin/Plugin.hpp" | ||||
#if defined ARCH_MAC | #if defined ARCH_MAC | ||||
@@ -52,10 +53,7 @@ void init() { | |||||
// Convert to short path to avoid Unicode | // Convert to short path to avoid Unicode | ||||
wchar_t moduleBufShortW[MAX_PATH]; | wchar_t moduleBufShortW[MAX_PATH]; | ||||
GetShortPathNameW(moduleBufW, moduleBufShortW, LENGTHOF(moduleBufShortW)); | GetShortPathNameW(moduleBufW, moduleBufShortW, LENGTHOF(moduleBufShortW)); | ||||
// Convert to UTF-8. | |||||
char moduleBuf[MAX_PATH]; | |||||
WideCharToMultiByte(CP_UTF8, 0, moduleBufShortW, -1, moduleBuf, sizeof(moduleBuf), NULL, NULL); | |||||
systemDir = moduleBuf; | |||||
systemDir = string::fromWstring(moduleBufShortW); | |||||
#endif | #endif | ||||
#if defined ARCH_LIN | #if defined ARCH_LIN | ||||
// Users should launch Rack from their terminal in the system directory | // Users should launch Rack from their terminal in the system directory | ||||
@@ -74,14 +72,11 @@ void init() { | |||||
// Get "My Documents" folder | // Get "My Documents" folder | ||||
wchar_t documentsBufW[MAX_PATH] = L"."; | wchar_t documentsBufW[MAX_PATH] = L"."; | ||||
HRESULT result = SHGetFolderPathW(NULL, CSIDL_MYDOCUMENTS, NULL, SHGFP_TYPE_CURRENT, documentsBufW); | HRESULT result = SHGetFolderPathW(NULL, CSIDL_MYDOCUMENTS, NULL, SHGFP_TYPE_CURRENT, documentsBufW); | ||||
// assert(result == S_OK); | |||||
assert(result == S_OK); | |||||
// Convert to short path to avoid Unicode | // Convert to short path to avoid Unicode | ||||
wchar_t documentsBufShortW[MAX_PATH]; | wchar_t documentsBufShortW[MAX_PATH]; | ||||
GetShortPathNameW(documentsBufW, documentsBufShortW, LENGTHOF(documentsBufShortW)); | GetShortPathNameW(documentsBufW, documentsBufShortW, LENGTHOF(documentsBufShortW)); | ||||
// Convert to UTF-8. | |||||
char documentsBuf[MAX_PATH]; | |||||
WideCharToMultiByte(CP_UTF8, 0, documentsBufShortW, -1, documentsBuf, sizeof(documentsBuf), NULL, NULL); | |||||
userDir = documentsBuf; | |||||
userDir = string::fromWstring(documentsBufShortW); | |||||
userDir += "/Rack"; | userDir += "/Rack"; | ||||
#endif | #endif | ||||
#if defined ARCH_MAC | #if defined ARCH_MAC | ||||
@@ -1,4 +1,6 @@ | |||||
#include "string.hpp" | #include "string.hpp" | ||||
#include <locale> // for wstring_convert | |||||
#include <codecvt> // for codecvt_utf8_utf16 | |||||
#include <cctype> // for tolower and toupper | #include <cctype> // for tolower and toupper | ||||
#include <algorithm> // for transform | #include <algorithm> // for transform | ||||
#include <libgen.h> // for dirname and basename | #include <libgen.h> // for dirname and basename | ||||
@@ -8,6 +10,16 @@ namespace rack { | |||||
namespace string { | namespace string { | ||||
std::string fromWstring(const std::wstring &s) { | |||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter; | |||||
return converter.to_bytes(s); | |||||
} | |||||
std::wstring toWstring(const std::string &s) { | |||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter; | |||||
return converter.from_bytes(s); | |||||
} | |||||
std::string f(const char *format, ...) { | std::string f(const char *format, ...) { | ||||
va_list args; | va_list args; | ||||
va_start(args, format); | va_start(args, format); | ||||
@@ -85,9 +85,8 @@ void copyFile(const std::string &srcPath, const std::string &destPath) { | |||||
void createDirectory(const std::string &path) { | void createDirectory(const std::string &path) { | ||||
#if defined ARCH_WIN | #if defined ARCH_WIN | ||||
wchar_t pathW[MAX_PATH]; | |||||
MultiByteToWideChar(CP_UTF8, 0, path.c_str(), -1, pathW, LENGTHOF(pathW)); | |||||
CreateDirectoryW(pathW, NULL); | |||||
std::wstring pathW = string::toWstring(path); | |||||
CreateDirectoryW(pathW.c_str(), NULL); | |||||
#else | #else | ||||
mkdir(path.c_str(), 0755); | mkdir(path.c_str(), 0755); | ||||
#endif | #endif | ||||
@@ -162,9 +161,8 @@ void openBrowser(const std::string &url) { | |||||
std::system(command.c_str()); | std::system(command.c_str()); | ||||
#endif | #endif | ||||
#if defined ARCH_WIN | #if defined ARCH_WIN | ||||
wchar_t urlW[1024]; | |||||
MultiByteToWideChar(CP_UTF8, 0, url.c_str(), -1, urlW, LENGTHOF(urlW)); | |||||
ShellExecuteW(NULL, L"open", urlW, NULL, NULL, SW_SHOWNORMAL); | |||||
std::wstring urlW = string::toWstring(url); | |||||
ShellExecuteW(NULL, L"open", urlW.c_str(), NULL, NULL, SW_SHOWNORMAL); | |||||
#endif | #endif | ||||
} | } | ||||
@@ -174,9 +172,8 @@ void openFolder(const std::string &path) { | |||||
(void) std::system(command.c_str()); | (void) std::system(command.c_str()); | ||||
#endif | #endif | ||||
#if defined ARCH_WIN | #if defined ARCH_WIN | ||||
wchar_t pathW[MAX_PATH]; | |||||
MultiByteToWideChar(CP_UTF8, 0, path.c_str(), -1, pathW, LENGTHOF(pathW)); | |||||
ShellExecuteW(NULL, L"explorer", pathW, NULL, NULL, SW_SHOWNORMAL); | |||||
std::wstring pathW = string::toWstring(path); | |||||
ShellExecuteW(NULL, L"explorer", pathW.c_str(), NULL, NULL, SW_SHOWNORMAL); | |||||
#endif | #endif | ||||
} | } | ||||
@@ -190,9 +187,8 @@ void runProcessAsync(const std::string &path) { | |||||
startupInfo.cb = sizeof(startupInfo); | startupInfo.cb = sizeof(startupInfo); | ||||
std::memset(&processInfo, 0, sizeof(processInfo)); | std::memset(&processInfo, 0, sizeof(processInfo)); | ||||
wchar_t pathW[MAX_PATH]; | |||||
MultiByteToWideChar(CP_UTF8, 0, path.c_str(), -1, pathW, LENGTHOF(pathW)); | |||||
CreateProcessW(pathW, NULL, | |||||
std::wstring pathW = string::toWstring(path); | |||||
CreateProcessW(pathW.c_str(), NULL, | |||||
NULL, NULL, false, 0, NULL, NULL, | NULL, NULL, false, 0, NULL, NULL, | ||||
&startupInfo, &processInfo); | &startupInfo, &processInfo); | ||||
#endif | #endif | ||||