wide-string equivalents.tags/v2.0.0
| @@ -34,6 +34,7 @@ endif | |||||
| ifdef ARCH_WIN | ifdef ARCH_WIN | ||||
| FLAGS += -DARCH_WIN | FLAGS += -DARCH_WIN | ||||
| FLAGS += -D_USE_MATH_DEFINES | FLAGS += -D_USE_MATH_DEFINES | ||||
| FLAGS += -municode | |||||
| CXXFLAGS += -Wsuggest-override | CXXFLAGS += -Wsuggest-override | ||||
| endif | endif | ||||
| @@ -164,3 +164,23 @@ struct Exception : std::runtime_error { | |||||
| } // namespace rack | } // namespace rack | ||||
| #if defined ARCH_WIN | |||||
| // Windows C standard functions are ASCII-8 instead of UTF-8, so redirect these functions to wrappers which convert to UTF-8 | |||||
| #define fopen fopen_utf8 | |||||
| #define remove remove_utf8 | |||||
| #define rename rename_utf8 | |||||
| extern "C" { | |||||
| FILE* fopen_utf8(const char* filename, const char* mode); | |||||
| int remove_utf8(const char* path); | |||||
| int rename_utf8(const char* oldname, const char* newname); | |||||
| } | |||||
| namespace std { | |||||
| using ::fopen_utf8; | |||||
| using ::remove_utf8; | |||||
| using ::rename_utf8; | |||||
| } | |||||
| #endif | |||||
| @@ -0,0 +1,39 @@ | |||||
| #include <common.hpp> | |||||
| #if defined ARCH_WIN | |||||
| #include <windows.h> | |||||
| static wchar_t* utf8_to_w(const char* str) { | |||||
| int len = MultiByteToWideChar(CP_UTF8, 0, str, -1, 0, 0); | |||||
| wchar_t* strW = (wchar_t*) malloc(len * sizeof(wchar_t)); | |||||
| MultiByteToWideChar(CP_UTF8, 0, str, -1, strW, len); | |||||
| return strW; | |||||
| } | |||||
| FILE* fopen_utf8(const char* filename, const char* mode) { | |||||
| wchar_t* filenameW = utf8_to_w(filename); | |||||
| wchar_t* modeW = utf8_to_w(mode); | |||||
| FILE* file = _wfopen(filenameW, modeW); | |||||
| free(filenameW); | |||||
| free(modeW); | |||||
| return file; | |||||
| } | |||||
| int remove_utf8(const char* path) { | |||||
| wchar_t* pathW = utf8_to_w(path); | |||||
| int ret = _wremove(pathW); | |||||
| free(pathW); | |||||
| return ret; | |||||
| } | |||||
| int rename_utf8(const char* oldname, const char* newname) { | |||||
| wchar_t* oldnameW = utf8_to_w(oldname); | |||||
| wchar_t* newnameW = utf8_to_w(newname); | |||||
| int ret = _wrename(oldnameW, newnameW); | |||||
| free(oldnameW); | |||||
| free(newnameW); | |||||
| return ret; | |||||
| } | |||||
| #endif | |||||
| @@ -58,7 +58,7 @@ int main(int argc, char* argv[]) { | |||||
| #if defined ARCH_WIN | #if defined ARCH_WIN | ||||
| // Windows global mutex to prevent multiple instances | // Windows global mutex to prevent multiple instances | ||||
| // Handle will be closed by Windows when the process ends | // Handle will be closed by Windows when the process ends | ||||
| HANDLE instanceMutex = CreateMutexA(NULL, true, app::APP_NAME.c_str()); | |||||
| HANDLE instanceMutex = CreateMutexW(NULL, true, string::toWstring(app::APP_NAME).c_str()); | |||||
| if (GetLastError() == ERROR_ALREADY_EXISTS) { | if (GetLastError() == ERROR_ALREADY_EXISTS) { | ||||
| osdialog_message(OSDIALOG_ERROR, OSDIALOG_OK, "Rack is already running. Multiple Rack instances are not supported."); | osdialog_message(OSDIALOG_ERROR, OSDIALOG_OK, "Rack is already running. Multiple Rack instances are not supported."); | ||||
| exit(1); | exit(1); | ||||
| @@ -23,7 +23,6 @@ | |||||
| #if defined ARCH_WIN | #if defined ARCH_WIN | ||||
| #include <windows.h> | #include <windows.h> | ||||
| #include <direct.h> | #include <direct.h> | ||||
| #define mkdir(_dir, _perms) _mkdir(_dir) | |||||
| #else | #else | ||||
| #include <dlfcn.h> | #include <dlfcn.h> | ||||
| #endif | #endif | ||||
| @@ -65,7 +64,8 @@ static InitCallback loadLibrary(Plugin* plugin) { | |||||
| // Load dynamic/shared library | // Load dynamic/shared library | ||||
| #if defined ARCH_WIN | #if defined ARCH_WIN | ||||
| SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS); | SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS); | ||||
| HINSTANCE handle = LoadLibrary(libraryFilename.c_str()); | |||||
| std::wstring libraryFilenameW = string::toWstring(libraryFilename); | |||||
| HINSTANCE handle = LoadLibraryW(libraryFilenameW.c_str()); | |||||
| SetErrorMode(0); | SetErrorMode(0); | ||||
| if (!handle) { | if (!handle) { | ||||
| int error = GetLastError(); | int error = GetLastError(); | ||||
| @@ -207,7 +207,7 @@ void init() { | |||||
| loadPlugin(""); | loadPlugin(""); | ||||
| // Get user plugins directory | // Get user plugins directory | ||||
| mkdir(asset::pluginsPath.c_str(), 0755); | |||||
| system::createDirectory(asset::pluginsPath); | |||||
| // Extract packages and load plugins | // Extract packages and load plugins | ||||
| extractPackages(asset::pluginsPath); | extractPackages(asset::pluginsPath); | ||||
| @@ -130,7 +130,7 @@ 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 | ||||
| std::wstring pathW = string::toWstring(path); | std::wstring pathW = string::toWstring(path); | ||||
| CreateDirectoryW(pathW.c_str(), NULL); | |||||
| _wmkdir(pathW.c_str()); | |||||
| #else | #else | ||||
| mkdir(path.c_str(), 0755); | mkdir(path.c_str(), 0755); | ||||
| #endif | #endif | ||||
| @@ -148,7 +148,12 @@ void createDirectories(const std::string& path) { | |||||
| void removeDirectory(const std::string& path) { | void removeDirectory(const std::string& path) { | ||||
| #if defined ARCH_WIN | |||||
| std::wstring pathW = string::toWstring(path); | |||||
| _wrmdir(pathW.c_str()); | |||||
| #else | |||||
| rmdir(path.c_str()); | rmdir(path.c_str()); | ||||
| #endif | |||||
| } | } | ||||