summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vcl/Library_vcl.mk1
-rw-r--r--vcl/inc/opengl/win/WinDeviceInfo.hxx3
-rw-r--r--vcl/opengl/win/WinDeviceInfo.cxx67
-rw-r--r--vcl/opengl/win/backlist.xml10
-rw-r--r--vcl/opengl/win/blocklist_parser.cxx304
-rw-r--r--vcl/opengl/win/blocklist_parser.hxx44
6 files changed, 396 insertions, 33 deletions
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 0ce40d39eb46..82fa50913cc5 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -663,6 +663,7 @@ ifeq ($(OS),WNT)
$(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/opengl/win/gdiimpl \
vcl/opengl/win/WinDeviceInfo \
+ vcl/opengl/win/blocklist_parser \
vcl/win/source/app/saldata \
vcl/win/source/app/salinfo \
vcl/win/source/app/salinst \
diff --git a/vcl/inc/opengl/win/WinDeviceInfo.hxx b/vcl/inc/opengl/win/WinDeviceInfo.hxx
index 21f14d9272bd..801329ae7073 100644
--- a/vcl/inc/opengl/win/WinDeviceInfo.hxx
+++ b/vcl/inc/opengl/win/WinDeviceInfo.hxx
@@ -73,6 +73,8 @@ enum DeviceVendor {
DeviceVendorMax
};
+bool ParseDriverVersion(const OUString& rString, uint64_t& rVersion);
+
struct DriverInfo
{
typedef std::vector<OUString> DeviceFamilyVector;
@@ -114,6 +116,7 @@ struct DriverInfo
static DeviceFamilyVector* mpDeviceFamilies[DeviceFamilyMax];
OUString maSuggestedVersion;
+ OUString maMsg;
};
#define GFX_DRIVER_VERSION(a,b,c,d) \
diff --git a/vcl/opengl/win/WinDeviceInfo.cxx b/vcl/opengl/win/WinDeviceInfo.cxx
index 91033243abec..1c02b0c0f3ab 100644
--- a/vcl/opengl/win/WinDeviceInfo.cxx
+++ b/vcl/opengl/win/WinDeviceInfo.cxx
@@ -339,9 +339,35 @@ bool SplitDriverVersion(const char *aSource, char *aAStr, char *aBStr, char *aCS
return true;
}
-bool ParseDriverVersion(const OUString& aVersion, uint64_t *aNumericVersion)
+/* Other interesting places for info:
+ * IDXGIAdapter::GetDesc()
+ * IDirectDraw7::GetAvailableVidMem()
+ * e->GetAvailableTextureMem()
+ * */
+
+template<typename T> void appendIntegerWithPadding(OUString& rString, T value, sal_uInt32 nChars)
+{
+ rString += "0x";
+ OUString aValue = OUString::number(value, 16);
+ sal_Int32 nLength = aValue.getLength();
+ sal_uInt32 nPadLength = nChars - nLength;
+ assert(nPadLength >= 0);
+ OUStringBuffer aBuffer;
+ for (sal_uInt32 i = 0; i < nPadLength; ++i)
+ {
+ aBuffer.append("0");
+ }
+ rString += aBuffer.makeStringAndClear() + aValue;
+}
+
+#define DEVICE_KEY_PREFIX L"\\Registry\\Machine\\"
+}
+
+namespace wgl {
+
+bool ParseDriverVersion(const OUString& aVersion, uint64_t& rNumericVersion)
{
- *aNumericVersion = 0;
+ rNumericVersion = 0;
#if defined(WIN32)
int a, b, c, d;
@@ -365,37 +391,12 @@ bool ParseDriverVersion(const OUString& aVersion, uint64_t *aNumericVersion)
if (c < 0 || c > 0xffff) return false;
if (d < 0 || d > 0xffff) return false;
- *aNumericVersion = GFX_DRIVER_VERSION(a, b, c, d);
+ rNumericVersion = GFX_DRIVER_VERSION(a, b, c, d);
return true;
#else
return false;
#endif
}
-/* Other interesting places for info:
- * IDXGIAdapter::GetDesc()
- * IDirectDraw7::GetAvailableVidMem()
- * e->GetAvailableTextureMem()
- * */
-
-template<typename T> void appendIntegerWithPadding(OUString& rString, T value, sal_uInt32 nChars)
-{
- rString += "0x";
- OUString aValue = OUString::number(value, 16);
- sal_Int32 nLength = aValue.getLength();
- sal_uInt32 nPadLength = nChars - nLength;
- assert(nPadLength >= 0);
- OUStringBuffer aBuffer;
- for (sal_uInt32 i = 0; i < nPadLength; ++i)
- {
- aBuffer.append("0");
- }
- rString += aBuffer.makeStringAndClear() + aValue;
-}
-
-#define DEVICE_KEY_PREFIX L"\\Registry\\Machine\\"
-}
-
-namespace wgl {
uint64_t DriverInfo::allDriverVersions = ~(uint64_t(0));
DriverInfo::DeviceFamilyVector* const DriverInfo::allDevices = nullptr;
@@ -627,7 +628,7 @@ WinOpenGLDeviceInfo::~WinOpenGLDeviceInfo()
bool WinOpenGLDeviceInfo::FindBlocklistedDeviceInList()
{
uint64_t driverVersion;
- ParseDriverVersion(maDriverVersion, &driverVersion);
+ wgl::ParseDriverVersion(maDriverVersion, driverVersion);
wgl::OperatingSystem eOS = WindowsVersionToOperatingSystem(mnWindowsVersion);
bool match = false;
@@ -1014,10 +1015,10 @@ void WinOpenGLDeviceInfo::GetData()
uint64_t dllNumericVersion = 0, dllNumericVersion2 = 0,
driverNumericVersion = 0, knownSafeMismatchVersion = 0;
- ParseDriverVersion(aDLLVersion, &dllNumericVersion);
- ParseDriverVersion(aDLLVersion2, &dllNumericVersion2);
- ParseDriverVersion(maDriverVersion, &driverNumericVersion);
- ParseDriverVersion("9.17.10.0", &knownSafeMismatchVersion);
+ wgl::ParseDriverVersion(aDLLVersion, dllNumericVersion);
+ wgl::ParseDriverVersion(aDLLVersion2, dllNumericVersion2);
+ wgl::ParseDriverVersion(maDriverVersion, driverNumericVersion);
+ wgl::ParseDriverVersion("9.17.10.0", knownSafeMismatchVersion);
// If there's a driver version mismatch, consider this harmful only when
// the driver version is less than knownSafeMismatchVersion. See the
diff --git a/vcl/opengl/win/backlist.xml b/vcl/opengl/win/backlist.xml
new file mode 100644
index 000000000000..b4cac2b1402c
--- /dev/null
+++ b/vcl/opengl/win/backlist.xml
@@ -0,0 +1,10 @@
+<root>
+ <whitelist>
+ <device os="7" vendor="intel" compare="equal" version="10.18.10.3412">
+ <msg>Moggi's Windows OpenGL driver</msg>
+ </device>
+ </whitelist>
+ <blacklist>
+
+ </blacklist>
+</root>
diff --git a/vcl/opengl/win/blocklist_parser.cxx b/vcl/opengl/win/blocklist_parser.cxx
new file mode 100644
index 000000000000..35301737bb09
--- /dev/null
+++ b/vcl/opengl/win/blocklist_parser.cxx
@@ -0,0 +1,304 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "blocklist_parser.hxx"
+
+WinBlocklistParser::WinBlocklistParser(const OUString& rURL,
+ std::vector<wgl::DriverInfo>& rDriverList):
+ maURL(rURL),
+ mrDriverList(rDriverList)
+{
+}
+
+void WinBlocklistParser::parse()
+{
+ xmlreader::XmlReader aReader(maURL);
+ handleContent(aReader);
+}
+
+namespace {
+
+wgl::OperatingSystem getOperatingSystem(const OString& rString)
+{
+ if (rString == "all")
+ {
+ return wgl::DRIVER_OS_ALL;
+ }
+ else if (rString == "xp")
+ {
+ return wgl::DRIVER_OS_WINDOWS_XP;
+ }
+ else if (rString == "server2003")
+ {
+ return wgl::DRIVER_OS_WINDOWS_SERVER_2003;
+ }
+ else if (rString == "vista")
+ {
+ return wgl::DRIVER_OS_WINDOWS_VISTA;
+ }
+ else if (rString == "7")
+ {
+ return wgl::DRIVER_OS_WINDOWS_7;
+ }
+ else if (rString == "8")
+ {
+ return wgl::DRIVER_OS_WINDOWS_8;
+ }
+ else if (rString == "8_1")
+ {
+ return wgl::DRIVER_OS_WINDOWS_8_1;
+ }
+
+ return wgl::DRIVER_OS_UNKNOWN;
+}
+
+wgl::VersionComparisonOp getComparison(const OString& rString)
+{
+ if (rString == "less")
+ {
+ return wgl::DRIVER_LESS_THAN;
+ }
+ else if (rString == "less_equal")
+ {
+ return wgl::DRIVER_LESS_THAN_OR_EQUAL;
+ }
+ else if (rString == "greater")
+ {
+ return wgl::DRIVER_GREATER_THAN;
+ }
+ else if (rString == "greater_equal")
+ {
+ return wgl::DRIVER_GREATER_THAN_OR_EQUAL;
+ }
+ else if (rString == "equal")
+ {
+ return wgl::DRIVER_EQUAL;
+ }
+ else if (rString == "not_equal")
+ {
+ return wgl::DRIVER_NOT_EQUAL;
+ }
+ else if (rString == "between_exclusive")
+ {
+ return wgl::DRIVER_BETWEEN_EXCLUSIVE;
+ }
+ else if (rString == "between_inclusive")
+ {
+ return wgl::DRIVER_BETWEEN_INCLUSIVE;
+ }
+ else if (rString == "between_inclusive_start")
+ {
+ return wgl::DRIVER_BETWEEN_INCLUSIVE_START;
+ }
+
+ throw InvalidFileException();
+}
+
+uint64_t getVersion(const OString& rString)
+{
+ OUString aString = OStringToOUString(rString, RTL_TEXTENCODING_UTF8);
+ uint64_t nVersion;
+ bool bResult = wgl::ParseDriverVersion(aString, nVersion);
+
+ if (!bResult)
+ {
+ throw InvalidFileException();
+ }
+
+ return nVersion;
+}
+
+}
+
+void WinBlocklistParser::handleDevice(wgl::DriverInfo& rDriver, xmlreader::XmlReader& rReader)
+{
+ if (meBlockType == BlockType::WHITELIST)
+ {
+ rDriver.mbWhitelisted = true;
+ }
+ else if (meBlockType == BlockType::UNKNOWN)
+ {
+ throw InvalidFileException();
+ }
+
+ xmlreader::Span name;
+ int nsId;
+
+ while (rReader.nextAttribute(&nsId, &name))
+ {
+ if (name.equals("os"))
+ {
+ xmlreader::Span name = rReader.getAttributeValue(false);
+ OString sOS(name.begin, name.length);
+ rDriver.meOperatingSystem = getOperatingSystem(sOS);
+ }
+ else if (name.equals("vendor"))
+ {
+ name = rReader.getAttributeValue(false);
+ OString sVendor(name.begin, name.length);
+
+ // TODO: moggi: check that only valid vendors are imported
+ OUString aVendor = OStringToOUString(sVendor, RTL_TEXTENCODING_UTF8);
+ rDriver.maAdapterVendor = aVendor;
+ }
+ else if (name.equals("device"))
+ {
+ name = rReader.getAttributeValue(false);
+ OString sDevice(name.begin, name.length);
+ }
+ else if (name.equals("compare"))
+ {
+ name = rReader.getAttributeValue(false);
+ OString sCompare(name.begin, name.length);
+ rDriver.meComparisonOp = getComparison(sCompare);
+ }
+ else if (name.equals("version"))
+ {
+ name = rReader.getAttributeValue(false);
+ OString sVersion(name.begin, name.length);
+ rDriver.mnDriverVersion = getVersion(sVersion);
+ }
+ else if (name.equals("minVersion"))
+ {
+ name = rReader.getAttributeValue(false);
+ OString sMinVersion(name.begin, name.length);
+ rDriver.mnDriverVersion = getVersion(sMinVersion);
+ }
+ else if (name.equals("maxVersion"))
+ {
+ name = rReader.getAttributeValue(false);
+ OString sMaxVersion(name.begin, name.length);
+ rDriver.mnDriverVersionMax = getVersion(sMaxVersion);
+ }
+ }
+
+ int nLevel = 1;
+ bool bInMsg = false;
+ while(true)
+ {
+ xmlreader::Span name;
+ int nsId;
+
+ xmlreader::XmlReader::Result res = rReader.nextItem(
+ xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
+
+ if (res == xmlreader::XmlReader::RESULT_BEGIN)
+ {
+ ++nLevel;
+ if (nLevel > 2)
+ throw InvalidFileException();
+
+ if (name.equals("msg"))
+ {
+ bInMsg = true;
+ }
+ else
+ throw InvalidFileException();
+ }
+ else if (res == xmlreader::XmlReader::RESULT_END)
+ {
+ --nLevel;
+ bInMsg = false;
+ if (!nLevel)
+ break;
+ }
+ else if (res == xmlreader::XmlReader::RESULT_TEXT)
+ {
+ if (bInMsg)
+ {
+ OString sMsg(name.begin, name.length);
+ rDriver.maMsg = OStringToOUString(sMsg, RTL_TEXTENCODING_UTF8);
+ }
+ }
+ }
+}
+
+void WinBlocklistParser::handleList(xmlreader::XmlReader& rReader)
+{
+ xmlreader::Span name;
+ int nsId;
+
+ while (true)
+ {
+ xmlreader::XmlReader::Result res = rReader.nextItem(
+ xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
+
+ if (res == xmlreader::XmlReader::RESULT_BEGIN)
+ {
+ if (name.equals("device"))
+ {
+ wgl::DriverInfo aDriver;
+ handleDevice(aDriver, rReader);
+ mrDriverList.push_back(aDriver);
+ }
+ else if (name.equals("deviceRange"))
+ {
+ wgl::DriverInfo aDriver;
+ handleDevice(aDriver, rReader);
+ mrDriverList.push_back(aDriver);
+ }
+ else
+ {
+ throw InvalidFileException();
+ }
+ }
+ else if (res == xmlreader::XmlReader::RESULT_END)
+ {
+ break;
+ }
+ }
+}
+
+void WinBlocklistParser::handleContent(xmlreader::XmlReader& rReader)
+{
+ while (true)
+ {
+ xmlreader::Span name;
+ int nsId;
+
+ xmlreader::XmlReader::Result res = rReader.nextItem(
+ xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
+
+ if (res == xmlreader::XmlReader::RESULT_BEGIN)
+ {
+ if (name.equals("whitelist"))
+ {
+ meBlockType = BlockType::WHITELIST;
+ handleList(rReader);
+ }
+ else if (name.equals("blacklist"))
+ {
+ meBlockType = BlockType::BLACKLIST;
+ handleList(rReader);
+ }
+ else if (name.equals("root"))
+ {
+ }
+ else
+ {
+ throw InvalidFileException();
+ }
+ }
+ else if (res == xmlreader::XmlReader::RESULT_END)
+ {
+ if (name.equals("whitelist")
+ ||
+ name.equals("blacklist"))
+ {
+ meBlockType = BlockType::UNKNOWN;
+ }
+ }
+ else if (res == xmlreader::XmlReader::RESULT_DONE)
+ {
+ break;
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/win/blocklist_parser.hxx b/vcl/opengl/win/blocklist_parser.hxx
new file mode 100644
index 000000000000..c34af0ad3403
--- /dev/null
+++ b/vcl/opengl/win/blocklist_parser.hxx
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "opengl/win/WinDeviceInfo.hxx"
+
+#include <xmlreader/xmlreader.hxx>
+
+#include <vector>
+
+class InvalidFileException
+{
+};
+
+class WinBlocklistParser
+{
+ WinBlocklistParser(const OUString& rURL, std::vector<wgl::DriverInfo>& rDriverList);
+ void parse();
+
+private:
+ void handleDevice(wgl::DriverInfo& rDriver, xmlreader::XmlReader& rReader);
+
+ void handleList(xmlreader::XmlReader& rReader);
+ void handleContent(xmlreader::XmlReader& rReader);
+
+
+ enum class BlockType
+ {
+ WHITELIST,
+ BLACKLIST,
+ UNKNOWN
+ };
+
+ BlockType meBlockType;
+ std::vector<wgl::DriverInfo>& mrDriverList;
+ OUString maURL;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */