summaryrefslogtreecommitdiffstats
path: root/accessible/windows/msaa/Compatibility.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'accessible/windows/msaa/Compatibility.cpp')
-rw-r--r--accessible/windows/msaa/Compatibility.cpp112
1 files changed, 112 insertions, 0 deletions
diff --git a/accessible/windows/msaa/Compatibility.cpp b/accessible/windows/msaa/Compatibility.cpp
new file mode 100644
index 000000000..31026c586
--- /dev/null
+++ b/accessible/windows/msaa/Compatibility.cpp
@@ -0,0 +1,112 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* 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 "Compatibility.h"
+
+#include "nsWinUtils.h"
+#include "Statistics.h"
+
+#include "mozilla/Preferences.h"
+
+using namespace mozilla;
+using namespace mozilla::a11y;
+
+/**
+ * Return true if module version is lesser than the given version.
+ */
+bool
+IsModuleVersionLessThan(HMODULE aModuleHandle, DWORD aMajor, DWORD aMinor)
+{
+ wchar_t fileName[MAX_PATH];
+ ::GetModuleFileNameW(aModuleHandle, fileName, MAX_PATH);
+
+ DWORD dummy = 0;
+ DWORD length = ::GetFileVersionInfoSizeW(fileName, &dummy);
+
+ LPBYTE versionInfo = new BYTE[length];
+ ::GetFileVersionInfoW(fileName, 0, length, versionInfo);
+
+ UINT uLen;
+ VS_FIXEDFILEINFO* fixedFileInfo = nullptr;
+ ::VerQueryValueW(versionInfo, L"\\", (LPVOID*)&fixedFileInfo, &uLen);
+ DWORD dwFileVersionMS = fixedFileInfo->dwFileVersionMS;
+ DWORD dwFileVersionLS = fixedFileInfo->dwFileVersionLS;
+ delete [] versionInfo;
+
+ DWORD dwLeftMost = HIWORD(dwFileVersionMS);
+ DWORD dwSecondRight = HIWORD(dwFileVersionLS);
+ return (dwLeftMost < aMajor ||
+ (dwLeftMost == aMajor && dwSecondRight < aMinor));
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Compatibility
+////////////////////////////////////////////////////////////////////////////////
+
+uint32_t Compatibility::sConsumers = Compatibility::UNKNOWN;
+
+void
+Compatibility::Init()
+{
+ // Note we collect some AT statistics/telemetry here for convenience.
+
+ HMODULE jawsHandle = ::GetModuleHandleW(L"jhook");
+ if (jawsHandle)
+ sConsumers |= (IsModuleVersionLessThan(jawsHandle, 8, 2173)) ?
+ OLDJAWS : JAWS;
+
+ if (::GetModuleHandleW(L"gwm32inc"))
+ sConsumers |= WE;
+
+ if (::GetModuleHandleW(L"dolwinhk"))
+ sConsumers |= DOLPHIN;
+
+ if (::GetModuleHandleW(L"STSA32"))
+ sConsumers |= SEROTEK;
+
+ if (::GetModuleHandleW(L"nvdaHelperRemote"))
+ sConsumers |= NVDA;
+
+ if (::GetModuleHandleW(L"OsmHooks"))
+ sConsumers |= COBRA;
+
+ if (::GetModuleHandleW(L"WebFinderRemote"))
+ sConsumers |= ZOOMTEXT;
+
+ if (::GetModuleHandleW(L"Kazahook"))
+ sConsumers |= KAZAGURU;
+
+ if (::GetModuleHandleW(L"TextExtractorImpl32") ||
+ ::GetModuleHandleW(L"TextExtractorImpl64"))
+ sConsumers |= YOUDAO;
+
+ if (::GetModuleHandleW(L"uiautomation") ||
+ ::GetModuleHandleW(L"uiautomationcore"))
+ sConsumers |= UIAUTOMATION;
+
+ // If we have a known consumer remove the unknown bit.
+ if (sConsumers != Compatibility::UNKNOWN)
+ sConsumers ^= Compatibility::UNKNOWN;
+
+ // Gather telemetry
+ uint32_t temp = sConsumers;
+ for (int i = 0; temp; i++) {
+ if (temp & 0x1)
+ statistics::A11yConsumers(i);
+
+ temp >>= 1;
+ }
+
+ // Turn off new tab switching for Jaws and WE.
+ if (sConsumers & (JAWS | OLDJAWS | WE)) {
+ // Check to see if the pref for disallowing CtrlTab is already set. If so,
+ // bail out (respect the user settings). If not, set it.
+ if (!Preferences::HasUserValue("browser.ctrlTab.disallowForScreenReaders"))
+ Preferences::SetBool("browser.ctrlTab.disallowForScreenReaders", true);
+ }
+}
+