From 2224c988afc50453ad5b8eed6a060529cefd11da Mon Sep 17 00:00:00 2001 From: Cyano Hao Date: Fri, 27 Sep 2024 21:25:15 +0800 Subject: [PATCH] Implement GCC ACP detection (#495) * implement GCC ACP detection * minor fix --- RedPandaIDE/settings.cpp | 26 ++++------------------- RedPandaIDE/settings.h | 6 ++++++ RedPandaIDE/utils.cpp | 45 ++++++++++++++++++++++++++++++++++++++++ RedPandaIDE/utils.h | 12 +++++++++++ RedPandaIDE/xmake.lua | 2 +- 5 files changed, 68 insertions(+), 23 deletions(-) diff --git a/RedPandaIDE/settings.cpp b/RedPandaIDE/settings.cpp index 9b9bbcfd..b1e044a5 100644 --- a/RedPandaIDE/settings.cpp +++ b/RedPandaIDE/settings.cpp @@ -2920,6 +2920,7 @@ bool Settings::CompilerSet::isOutputExecutable(CompilationStage stage) return stage == CompilationStage::GenerateExecutable; } +#ifdef Q_OS_WINDOWS bool Settings::CompilerSet::isDebugInfoUsingUTF8() const { switch(mCompilerType) { @@ -2927,30 +2928,10 @@ bool Settings::CompilerSet::isDebugInfoUsingUTF8() const case CompilerType::GCC_UTF8: return true; case CompilerType::GCC: -#ifdef Q_OS_WIN - if (mainVersion()>=13) { - bool isOk; - int productVersion = QSysInfo::productVersion().toInt(&isOk); - // qDebug()<=10; - } -#else - break; -#endif + return applicationIsUtf8(mCCompiler); default: - break; + return false; } - return false; } bool Settings::CompilerSet::forceUTF8() const @@ -2962,6 +2943,7 @@ bool Settings::CompilerSet::isCompilerInfoUsingUTF8() const { return isDebugInfoUsingUTF8(); } +#endif const QString &Settings::CompilerSet::assemblingSuffix() const { diff --git a/RedPandaIDE/settings.h b/RedPandaIDE/settings.h index b5f84534..8463669c 100644 --- a/RedPandaIDE/settings.h +++ b/RedPandaIDE/settings.h @@ -1454,9 +1454,15 @@ public: bool isOutputExecutable(); bool isOutputExecutable(Settings::CompilerSet::CompilationStage stage); +#ifdef Q_OS_WINDOWS bool isDebugInfoUsingUTF8() const; bool forceUTF8() const; bool isCompilerInfoUsingUTF8() const; +#else + constexpr bool isDebugInfoUsingUTF8() const { return true; } + constexpr bool forceUTF8() const { return true; } + constexpr bool isCompilerInfoUsingUTF8() const { return true; } +#endif bool persistInAutoFind() const; void setPersistInAutoFind(bool newPersistInAutoFind); diff --git a/RedPandaIDE/utils.cpp b/RedPandaIDE/utils.cpp index 2dd692ca..740e4de2 100644 --- a/RedPandaIDE/utils.cpp +++ b/RedPandaIDE/utils.cpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include "editor.h" #include "editorlist.h" #include "settings.h" @@ -792,3 +794,46 @@ ExternalResource::~ExternalResource() { Q_CLEANUP_RESOURCE(qsynedit_qmake_qmake_qm_files); Q_CLEANUP_RESOURCE(redpanda_qt_utils_qmake_qmake_qm_files); } + +#ifdef Q_OS_WINDOWS +bool applicationHasUtf8Manifest(const wchar_t *path) +{ + auto module = resourcePointer(LoadLibraryExW(path, nullptr, LOAD_LIBRARY_AS_DATAFILE), &FreeLibrary); + if (!module) + return false; + HRSRC resInfo = FindResourceW( + module.get(), + MAKEINTRESOURCEW(1) /* CREATEPROCESS_MANIFEST_RESOURCE_ID */, + MAKEINTRESOURCEW(24) /* RT_MANIFEST */); + if (!resInfo) + return false; + auto res = resourcePointer(LoadResource(module.get(), resInfo), &FreeResource); + if (!res) + return false; + char *data = (char *)LockResource(res.get()); + DWORD size = SizeofResource(module.get(), resInfo); + QByteArray manifest(data, size); + QDomDocument doc; + if (!doc.setContent(manifest)) + return false; + QDomNodeList acpNodes = doc.elementsByTagName("activeCodePage"); + if (acpNodes.isEmpty()) + return false; + QDomElement acpNode = acpNodes.item(0).toElement(); + // case sensitive + // ref. https://devblogs.microsoft.com/oldnewthing/20220531-00/?p=106697 + return acpNode.text() == QStringLiteral("UTF-8"); +} + +bool osSupportsUtf8Manifest() +{ + // since Windows 10 1903 (accurate build number unknown) + // ref. https://learn.microsoft.com/en-us/windows/apps/design/globalizing/use-utf8-code-page + return QOperatingSystemVersion::current().microVersion() >= 18362; +} + +bool applicationIsUtf8(const QString &path) +{ + return osSupportsUtf8Manifest() && applicationHasUtf8Manifest((wchar_t *)path.constData()); +} +#endif diff --git a/RedPandaIDE/utils.h b/RedPandaIDE/utils.h index 54e9dd06..ef4aac82 100644 --- a/RedPandaIDE/utils.h +++ b/RedPandaIDE/utils.h @@ -215,4 +215,16 @@ struct ExternalResource { ~ExternalResource(); }; +template +std::unique_ptr resourcePointer(T *pointer, D deleter) +{ + return {pointer, deleter}; +} + +#ifdef Q_OS_WINDOWS +bool applicationHasUtf8Manifest(const wchar_t *path); +bool osSupportsUtf8Manifest(); +bool applicationIsUtf8(const QString &path); +#endif + #endif // UTILS_H diff --git a/RedPandaIDE/xmake.lua b/RedPandaIDE/xmake.lua index 3d0ba3d4..0b28828c 100644 --- a/RedPandaIDE/xmake.lua +++ b/RedPandaIDE/xmake.lua @@ -4,7 +4,7 @@ target("RedPandaIDE") add_rules("qt.widgetapp", "qt.ts") add_deps("redpanda_qt_utils", "qsynedit") - add_frameworks("QtNetwork", "QtPrintSupport", "QtSvg") + add_frameworks("QtNetwork", "QtPrintSupport", "QtSvg", "QtXml") add_includedirs(".") -- defines