From 70accc289a077b2d05250676ed33369eeaa7df49 Mon Sep 17 00:00:00 2001 From: Louai Al-Khanji Date: Mon, 5 May 2014 14:49:04 +0300 Subject: [PATCH] Direct2D QPA: Check Direct2D version Since we require a relatively recent system, check the version of the direct2d dll on disk and report an error to the user if it is too old. Previously only a cryptic runtime error resulted from a direct2d version that was too old. Change-Id: I6c3955e1a98326fca6bcdc871b0a25291391ba88 Reviewed-by: Risto Avila Reviewed-by: Friedemann Kleint --- src/plugins/platforms/direct2d/direct2d.pro | 2 +- .../direct2d/qwindowsdirect2dintegration.cpp | 135 +++++++++++++++++- 2 files changed, 135 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/direct2d/direct2d.pro b/src/plugins/platforms/direct2d/direct2d.pro index 439d31fb56..03997f2737 100644 --- a/src/plugins/platforms/direct2d/direct2d.pro +++ b/src/plugins/platforms/direct2d/direct2d.pro @@ -9,7 +9,7 @@ QT *= core-private QT *= gui-private QT *= platformsupport-private -LIBS *= -ld2d1 -ld3d11 -ldwrite +LIBS *= -ld2d1 -ld3d11 -ldwrite -lVersion include(../windows/windows.pri) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp index 1a26d7029e..44fc7aa927 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp @@ -48,7 +48,8 @@ #include "qwindowscontext.h" -#include +#include +#include #include #include @@ -61,8 +62,140 @@ public: QWindowsDirect2DContext m_d2dContext; }; +class Direct2DVersion +{ +private: + Direct2DVersion() + : partOne(0) + , partTwo(0) + , partThree(0) + , partFour(0) + {} + + Direct2DVersion(int one, int two, int three, int four) + : partOne(one) + , partTwo(two) + , partThree(three) + , partFour(four) + {} + +public: + // 6.2.9200.16765 corresponds to Direct2D 1.1 on Windows 7 SP1 with Platform Update + enum { + D2DMinVersionPart1 = 6, + D2DMinVersionPart2 = 2, + D2DMinVersionPart3 = 9200, + D2DMinVersionPart4 = 16765 + }; + + static Direct2DVersion systemVersion() { + static const int bufSize = 512; + TCHAR filename[bufSize]; + + UINT i = GetSystemDirectory(filename, bufSize); + if (i > 0 && i < MAX_PATH) { + if (_tcscat_s(filename, MAX_PATH, __TEXT("\\d2d1.dll")) == 0) { + DWORD versionInfoSize = GetFileVersionInfoSize(filename, NULL); + if (versionInfoSize) { + QVector info(versionInfoSize); + if (GetFileVersionInfo(filename, NULL, versionInfoSize, info.data())) { + UINT size; + DWORD *fi; + + if (VerQueryValue(info.constData(), __TEXT("\\"), (LPVOID *) &fi, &size) && size) { + VS_FIXEDFILEINFO *verInfo = (VS_FIXEDFILEINFO *) fi; + return Direct2DVersion(HIWORD(verInfo->dwFileVersionMS), + LOWORD(verInfo->dwFileVersionMS), + HIWORD(verInfo->dwFileVersionLS), + LOWORD(verInfo->dwFileVersionLS)); + } + } + } + } + } + + return Direct2DVersion(); + } + + static Direct2DVersion minimumVersion() { + return Direct2DVersion(D2DMinVersionPart1, + D2DMinVersionPart2, + D2DMinVersionPart3, + D2DMinVersionPart4); + } + + bool isValid() const { + return partOne || partTwo || partThree || partFour; + } + + bool operator<(const Direct2DVersion &other) { + int c = cmp(partOne, other.partOne); + if (c > 0) + return false; + if (c < 0) + return true; + + c = cmp(partTwo, other.partTwo); + if (c > 0) + return false; + if (c < 0) + return true; + + c = cmp(partThree, other.partThree); + if (c > 0) + return false; + if (c < 0) + return true; + + c = cmp(partFour, other.partFour); + if (c > 0) + return false; + if (c < 0) + return true; + + return false; + } + + static Q_DECL_CONSTEXPR int cmp(int a, int b) { + return a - b; + } + + int partOne, partTwo, partThree, partFour; +}; + QWindowsDirect2DIntegration *QWindowsDirect2DIntegration::create(const QStringList ¶mList) { + Direct2DVersion systemVersion = Direct2DVersion::systemVersion(); + + if (systemVersion.isValid() && systemVersion < Direct2DVersion::minimumVersion()) { + QString msg = QCoreApplication::translate("QWindowsDirect2DIntegration", + "Qt cannot load the direct2d platform plugin because " \ + "the Direct2D version on this system is too old. The " \ + "minimum system requirement for this platform plugin " \ + "is Windows 7 SP1 with Platform Update.\n\n" \ + "The minimum Direct2D version required is %1.%2.%3.%4. " \ + "The Direct2D version on this system is %5.%6.%7.%8."); + + msg = msg.arg(Direct2DVersion::D2DMinVersionPart1) + .arg(Direct2DVersion::D2DMinVersionPart2) + .arg(Direct2DVersion::D2DMinVersionPart3) + .arg(Direct2DVersion::D2DMinVersionPart4) + .arg(systemVersion.partOne) + .arg(systemVersion.partTwo) + .arg(systemVersion.partThree) + .arg(systemVersion.partFour); + + QString caption = QCoreApplication::translate("QWindowsDirect2DIntegration", + "Cannot load direct2d platform plugin"); + + MessageBoxW(NULL, + msg.toStdWString().c_str(), + caption.toStdWString().c_str(), + MB_OK | MB_ICONERROR); + + return Q_NULLPTR; + } + QWindowsDirect2DIntegration *integration = new QWindowsDirect2DIntegration(paramList); if (!integration->init()) {