diff --git a/libmediation/CMakeLists.txt b/libmediation/CMakeLists.txt index 77e23e9e..e9a28135 100644 --- a/libmediation/CMakeLists.txt +++ b/libmediation/CMakeLists.txt @@ -8,6 +8,7 @@ add_library(mediation STATIC ) IF(WIN32) + target_compile_definitions(mediation PRIVATE "-DUNICODE") target_sources(mediation PRIVATE fs/osdep/file_win32.cpp) ELSE() target_sources(mediation PRIVATE fs/osdep/file_unix.cpp) diff --git a/libmediation/fs/directory.cpp b/libmediation/fs/directory.cpp index ad53b732..30cc2e37 100644 --- a/libmediation/fs/directory.cpp +++ b/libmediation/fs/directory.cpp @@ -97,7 +97,7 @@ bool createDir(const std::string& dirName, bool createParentDirs) parentDir == string("\\\\.\\") || // UNC patch prefix (strStartWith(parentDir, "\\\\.\\") && parentDir[parentDir.size() - 1] == '}')) // UNC patch prefix continue; - if (CreateDirectory(parentDir.c_str(), 0) == 0) + if (CreateDirectory(toWide(parentDir).data(), 0) == 0) { if (GetLastError() != ERROR_ALREADY_EXISTS) return false; @@ -110,7 +110,7 @@ bool createDir(const std::string& dirName, bool createParentDirs) #if __linux__ == 1 || (defined(__APPLE__) && defined(__MACH__)) return mkdir(dirName.c_str(), S_IREAD | S_IWRITE | S_IEXEC) == 0; #elif defined(_WIN32) - return CreateDirectory(dirName.c_str(), 0) != 0; + return CreateDirectory(toWide(dirName).data(), 0) != 0; #endif } @@ -119,7 +119,7 @@ bool deleteFile(const string& fileName) #if __linux__ == 1 || (defined(__APPLE__) && defined(__MACH__)) return unlink(fileName.c_str()) == 0; #else - if (DeleteFile(fileName.c_str())) + if (DeleteFile(toWide(fileName).data())) { return true; } @@ -129,7 +129,7 @@ bool deleteFile(const string& fileName) return false; } - return DeleteFile(fileName.c_str()) != 0; + return DeleteFile(toWide(fileName).data()) != 0; #endif } @@ -144,7 +144,8 @@ bool findFiles(const string& path, const string& fileMask, vector* fileL WIN32_FIND_DATA fileData; // Data structure describes the file found HANDLE hSearch; // Search handle returned by FindFirstFile - hSearch = FindFirstFile(TEXT(string(path + '/' + fileMask).c_str()), &fileData); + auto searchStr = toWide(path + '/' + fileMask); + hSearch = FindFirstFile(searchStr.data(), &fileData); if (hSearch == INVALID_HANDLE_VALUE) return false; @@ -152,8 +153,7 @@ bool findFiles(const string& path, const string& fileMask, vector* fileL { if (!(fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { - string fileName(fileData.cFileName); - + auto fileName = toUtf8(fileData.cFileName); fileList->push_back(savePaths ? (path + '/' + fileName) : fileName); } } while (FindNextFile(hSearch, &fileData)); @@ -168,7 +168,8 @@ bool findDirs(const string& path, vector* dirsList) WIN32_FIND_DATA fileData; // Data structure describes the file found HANDLE hSearch; // Search handle returned by FindFirstFile - hSearch = FindFirstFile(TEXT(string(path + "*").c_str()), &fileData); + auto searchStr = toWide(path + "*"); + hSearch = FindFirstFile(searchStr.data(), &fileData); if (hSearch == INVALID_HANDLE_VALUE) return false; @@ -176,7 +177,7 @@ bool findDirs(const string& path, vector* dirsList) { if (!(fileData.dwFileAttributes ^ FILE_ATTRIBUTE_DIRECTORY)) { - string dirName(fileData.cFileName); + auto dirName = toUtf8(fileData.cFileName); if ("." != dirName && ".." != dirName) dirsList->push_back(path + dirName + "/"); diff --git a/libmediation/fs/osdep/file_win32.cpp b/libmediation/fs/osdep/file_win32.cpp index 91e484d3..3ec2742c 100644 --- a/libmediation/fs/osdep/file_win32.cpp +++ b/libmediation/fs/osdep/file_win32.cpp @@ -59,7 +59,8 @@ File::File(const char* fName, unsigned int oflag, unsigned int systemDependentFl else systemDependentFlags = FILE_FLAG_RANDOM_ACCESS; } - m_impl = CreateFile(fName, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, systemDependentFlags, NULL); + m_impl = CreateFile(toWide(fName).data(), dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, + systemDependentFlags, NULL); if (m_impl == INVALID_HANDLE_VALUE) { throwFileError(); @@ -100,8 +101,8 @@ bool File::open(const char* fName, unsigned int oflag, unsigned int systemDepend } createDir(extractFileDir(fName), true); - - m_impl = CreateFile(fName, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, systemDependentFlags, NULL); + m_impl = CreateFile(toWide(fName).data(), dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, + systemDependentFlags, NULL); if (m_impl == INVALID_HANDLE_VALUE) { return false; diff --git a/libmediation/types/types.cpp b/libmediation/types/types.cpp index 4c359568..e0904551 100644 --- a/libmediation/types/types.cpp +++ b/libmediation/types/types.cpp @@ -488,3 +488,30 @@ uint32_t random32() static std::minstd_rand raand(dev()); return static_cast(raand()); } + +#ifdef _WIN32 +#include + +std::vector toWide(const std::string& utf8Str) { return toWide(utf8Str.c_str(), utf8Str.size()); } + +std::vector toWide(const char* utf8Str, int sz) +{ + auto requiredSiz = MultiByteToWideChar(CP_UTF8, 0, utf8Str, sz, nullptr, 0); + std::vector multiByteBuf(static_cast(requiredSiz)); + MultiByteToWideChar(CP_UTF8, 0, utf8Str, sz, multiByteBuf.data(), requiredSiz); + if (multiByteBuf.empty() || multiByteBuf.back() != 0) + { + multiByteBuf.push_back(0); + } + return multiByteBuf; +} + +std::string toUtf8(const wchar_t* wideStr) +{ + auto needed = WideCharToMultiByte(CP_UTF8, 0, wideStr, -1, nullptr, 0, nullptr, nullptr); + needed--; // includes terminating null byte, needless when returning a std::string. + std::string s(static_cast(needed), 0); + WideCharToMultiByte(CP_UTF8, 0, wideStr, -1, &s[0], needed, nullptr, nullptr); + return s; +} +#endif diff --git a/libmediation/types/types.h b/libmediation/types/types.h index c947b6ea..eb92a4ef 100644 --- a/libmediation/types/types.h +++ b/libmediation/types/types.h @@ -115,4 +115,10 @@ static uint32_t FOUR_CC(uint8_t a, uint8_t b, uint8_t c, uint8_t d) return my_ntohl((uint32_t(a) << 24) + (uint32_t(b) << 16) + (uint32_t(c) << 8) + uint32_t(d)); } +#ifdef _WIN32 +std::vector toWide(const char*, int sz = -1); +std::vector toWide(const std::string&); +std::string toUtf8(const wchar_t*); +#endif + #endif //__T_TYPES_H diff --git a/tsMuxer/CMakeLists.txt b/tsMuxer/CMakeLists.txt index 4836fd0c..9e38fd8c 100644 --- a/tsMuxer/CMakeLists.txt +++ b/tsMuxer/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required (VERSION 3.1) project (tsmuxer LANGUAGES CXX) -add_executable (tsmuxer +add_executable (tsmuxer WIN32 aac.cpp aacStreamReader.cpp AbstractDemuxer.cpp @@ -104,6 +104,7 @@ target_link_libraries(tsmuxer mediation ${THREADSLIB} ${ZLIB_LIBRARIES}) if (WIN32) target_sources(tsmuxer PRIVATE osdep/textSubtitlesRenderWin32.cpp) target_link_libraries(tsmuxer gdiplus) + target_compile_definitions(tsmuxer PRIVATE "-DUNICODE") else() target_sources(tsmuxer PRIVATE osdep/textSubtitlesRenderFT.cpp) target_link_libraries(tsmuxer ${FREETYPE2_LIBRARIES}) diff --git a/tsMuxer/main.cpp b/tsMuxer/main.cpp index fd3d39b3..7f401f5a 100644 --- a/tsMuxer/main.cpp +++ b/tsMuxer/main.cpp @@ -547,8 +547,29 @@ All parameters in this group start with two dashes:\n\ LTRACE(LT_INFO, 2, help); } +#ifdef _WIN32 +#include +int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) +{ + int argc; + auto argvWide = CommandLineToArgvW(GetCommandLineW(), &argc); + std::vector argv_utf8; + argv_utf8.reserve(static_cast(argc)); + for (int i = 0; i < argc; ++i) + { + argv_utf8.emplace_back(toUtf8(argvWide[i])); + } + LocalFree(argvWide); + std::vector argv; + argv.reserve(argv_utf8.size()); + for (auto&& s : argv_utf8) + { + argv.push_back(&s[0]); + } +#else int main(int argc, char** argv) { +#endif LTRACE(LT_INFO, 2, "tsMuxeR version " TSMUXER_VERSION << ". github.com/justdan96/tsMuxer"); int firstMplsOffset = 0; int firstM2tsOffset = 0; diff --git a/tsMuxerGUI/tsmuxerwindow.cpp b/tsMuxerGUI/tsmuxerwindow.cpp index 444ce17f..48c30af6 100644 --- a/tsMuxerGUI/tsmuxerwindow.cpp +++ b/tsMuxerGUI/tsmuxerwindow.cpp @@ -1176,7 +1176,7 @@ void splitLines(const QString &str, QList &strList) void TsMuxerWindow::addLines(const QByteArray &arr, QList &outList, bool isError) { - QString str = QString::fromLocal8Bit(arr); + QString str = QString::fromUtf8(arr); QList strList; splitLines(str, strList); QString text; @@ -2398,7 +2398,7 @@ bool TsMuxerWindow::saveMetaFile(const QString &metaName) msgBox.exec(); return false; } - QByteArray metaText = ui->memoMeta->toPlainText().toLocal8Bit(); + QByteArray metaText = ui->memoMeta->toPlainText().toUtf8(); file.write(metaText); file.close(); return true;