1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 2003
20 * the Initial Developer. All Rights Reserved.
23 * Original Author: Aaron Leventhal (aaronl@netscape.com)
25 * Alternatively, the contents of this file may be used under the terms of
26 * either of the GNU General Public License Version 2 or later (the "GPL"),
27 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
39 #include "nsAccessNodeWrap.h"
40 #include "ISimpleDOMNode_i.c"
41 #include "nsAccessibilityAtoms.h"
42 #include "nsIAccessibilityService.h"
43 #include "nsIAccessible.h"
44 #include "nsAttrName.h"
45 #include "nsIDocument.h"
46 #include "nsIDOMCSSStyleDeclaration.h"
47 #include "nsIDOMNodeList.h"
48 #include "nsIDOMNSHTMLElement.h"
49 #include "nsIDOMViewCSS.h"
51 #include "nsINameSpaceManager.h"
52 #include "nsIPrefService.h"
53 #include "nsIPrefBranch.h"
54 #include "nsIPresShell.h"
55 #include "nsPIDOMWindow.h"
56 #include "nsRootAccessible.h"
57 #include "nsIServiceManager.h"
58 #include "AccessibleApplication.h"
59 #include "nsApplicationAccessibleWrap.h"
61 /// the accessible library and cached methods
62 HINSTANCE
nsAccessNodeWrap::gmAccLib
= nsnull
;
63 HINSTANCE
nsAccessNodeWrap::gmUserLib
= nsnull
;
64 LPFNACCESSIBLEOBJECTFROMWINDOW
nsAccessNodeWrap::gmAccessibleObjectFromWindow
= nsnull
;
65 LPFNNOTIFYWINEVENT
nsAccessNodeWrap::gmNotifyWinEvent
= nsnull
;
66 LPFNGETGUITHREADINFO
nsAccessNodeWrap::gmGetGUIThreadInfo
= nsnull
;
68 PRBool
nsAccessNodeWrap::gIsEnumVariantSupportDisabled
= 0;
69 // Used to determine whether an IAccessible2 compatible screen reader is loaded.
70 PRBool
nsAccessNodeWrap::gIsIA2Disabled
= PR_FALSE
;
72 nsIAccessibleTextChangeEvent
*nsAccessNodeWrap::gTextEvent
= nsnull
;
74 // Pref to disallow CtrlTab preview functionality if JAWS or Window-Eyes are
76 #define CTRLTAB_DISALLOW_FOR_SCREEN_READERS_PREF "browser.ctrlTab.disallowForScreenReaders"
79 /* For documentation of the accessibility architecture,
80 * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
84 * Class nsAccessNodeWrap
87 //-----------------------------------------------------
89 //-----------------------------------------------------
91 nsAccessNodeWrap::nsAccessNodeWrap(nsIDOMNode
*aNode
, nsIWeakReference
* aShell
):
92 nsAccessNode(aNode
, aShell
)
96 //-----------------------------------------------------
98 //-----------------------------------------------------
99 nsAccessNodeWrap::~nsAccessNodeWrap()
103 //-----------------------------------------------------
104 // nsISupports methods
105 //-----------------------------------------------------
107 NS_IMPL_ISUPPORTS_INHERITED1(nsAccessNodeWrap
, nsAccessNode
, nsIWinAccessNode
);
109 //-----------------------------------------------------
110 // nsIWinAccessNode methods
111 //-----------------------------------------------------
114 nsAccessNodeWrap::QueryNativeInterface(REFIID aIID
, void** aInstancePtr
)
116 return QueryInterface(aIID
, aInstancePtr
);
119 //-----------------------------------------------------
120 // IUnknown interface methods - see iunknown.h for documentation
121 //-----------------------------------------------------
123 STDMETHODIMP
nsAccessNodeWrap::QueryInterface(REFIID iid
, void** ppv
)
127 if (IID_IUnknown
== iid
|| IID_ISimpleDOMNode
== iid
)
128 *ppv
= static_cast<ISimpleDOMNode
*>(this);
131 return E_NOINTERFACE
; //iid not supported.
133 (reinterpret_cast<IUnknown
*>(*ppv
))->AddRef();
138 nsAccessNodeWrap::QueryService(REFGUID guidService
, REFIID iid
, void** ppv
)
140 // Can get to IAccessibleApplication from any node via QS
141 if (iid
== IID_IAccessibleApplication
) {
142 nsRefPtr
<nsApplicationAccessibleWrap
> app
=
143 GetApplicationAccessible();
144 nsresult rv
= app
->QueryNativeInterface(iid
, ppv
);
145 return NS_SUCCEEDED(rv
) ? S_OK
: E_NOINTERFACE
;
149 * To get an ISimpleDOMNode, ISimpleDOMDocument, ISimpleDOMText
150 * or any IAccessible2 interface on should use IServiceProvider like this:
151 * -----------------------------------------------------------------------
152 * ISimpleDOMDocument *pAccDoc = NULL;
153 * IServiceProvider *pServProv = NULL;
154 * pAcc->QueryInterface(IID_IServiceProvider, (void**)&pServProv);
157 * pServProv->QueryService(unused, IID_ISimpleDOMDocument, (void**)&pAccDoc);
158 * pServProv->Release();
162 return QueryInterface(iid
, ppv
);
165 //-----------------------------------------------------
166 // ISimpleDOMNode methods
167 //-----------------------------------------------------
169 STDMETHODIMP
nsAccessNodeWrap::get_nodeInfo(
170 /* [out] */ BSTR __RPC_FAR
*aNodeName
,
171 /* [out] */ short __RPC_FAR
*aNameSpaceID
,
172 /* [out] */ BSTR __RPC_FAR
*aNodeValue
,
173 /* [out] */ unsigned int __RPC_FAR
*aNumChildren
,
174 /* [out] */ unsigned int __RPC_FAR
*aUniqueID
,
175 /* [out] */ unsigned short __RPC_FAR
*aNodeType
)
179 *aNodeValue
= nsnull
;
184 nsCOMPtr
<nsIContent
> content(do_QueryInterface(mDOMNode
));
186 PRUint16 nodeType
= 0;
187 mDOMNode
->GetNodeType(&nodeType
);
188 *aNodeType
=static_cast<unsigned short>(nodeType
);
190 if (*aNodeType
!= NODETYPE_TEXT
) {
191 nsAutoString nodeName
;
192 mDOMNode
->GetNodeName(nodeName
);
193 *aNodeName
= ::SysAllocString(nodeName
.get());
196 nsAutoString nodeValue
;
198 mDOMNode
->GetNodeValue(nodeValue
);
199 *aNodeValue
= ::SysAllocString(nodeValue
.get());
200 *aNameSpaceID
= content
? static_cast<short>(content
->GetNameSpaceID()) : 0;
202 // This is a unique ID for every content node. The 3rd party
203 // accessibility application can compare this to the childID we
204 // return for events such as focus events, to correlate back to
205 // data nodes in their internal object model.
207 GetUniqueID(&uniqueID
);
208 *aUniqueID
= - NS_PTR_TO_INT32(uniqueID
);
211 PRUint32 numChildren
= 0;
212 nsCOMPtr
<nsIDOMNodeList
> nodeList
;
213 mDOMNode
->GetChildNodes(getter_AddRefs(nodeList
));
214 if (nodeList
&& NS_OK
== nodeList
->GetLength(&numChildren
))
215 *aNumChildren
= static_cast<unsigned int>(numChildren
);
217 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
223 STDMETHODIMP
nsAccessNodeWrap::get_attributes(
224 /* [in] */ unsigned short aMaxAttribs
,
225 /* [length_is][size_is][out] */ BSTR __RPC_FAR
*aAttribNames
,
226 /* [length_is][size_is][out] */ short __RPC_FAR
*aNameSpaceIDs
,
227 /* [length_is][size_is][out] */ BSTR __RPC_FAR
*aAttribValues
,
228 /* [out] */ unsigned short __RPC_FAR
*aNumAttribs
)
233 nsCOMPtr
<nsIContent
> content(do_QueryInterface(mDOMNode
));
237 PRUint32 numAttribs
= content
->GetAttrCount();
239 if (numAttribs
> aMaxAttribs
)
240 numAttribs
= aMaxAttribs
;
241 *aNumAttribs
= static_cast<unsigned short>(numAttribs
);
243 for (PRUint32 index
= 0; index
< numAttribs
; index
++) {
244 aNameSpaceIDs
[index
] = 0; aAttribValues
[index
] = aAttribNames
[index
] = nsnull
;
245 nsAutoString attributeValue
;
246 const char *pszAttributeName
;
248 const nsAttrName
* name
= content
->GetAttrNameAt(index
);
249 aNameSpaceIDs
[index
] = static_cast<short>(name
->NamespaceID());
250 name
->LocalName()->GetUTF8String(&pszAttributeName
);
251 aAttribNames
[index
] = ::SysAllocString(NS_ConvertUTF8toUTF16(pszAttributeName
).get());
252 content
->GetAttr(name
->NamespaceID(), name
->LocalName(), attributeValue
);
253 aAttribValues
[index
] = ::SysAllocString(attributeValue
.get());
255 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
261 STDMETHODIMP
nsAccessNodeWrap::get_attributesForNames(
262 /* [in] */ unsigned short aNumAttribs
,
263 /* [length_is][size_is][in] */ BSTR __RPC_FAR
*aAttribNames
,
264 /* [length_is][size_is][in] */ short __RPC_FAR
*aNameSpaceID
,
265 /* [length_is][size_is][retval] */ BSTR __RPC_FAR
*aAttribValues
)
268 nsCOMPtr
<nsIDOMElement
> domElement(do_QueryInterface(mDOMNode
));
269 nsCOMPtr
<nsIContent
> content(do_QueryInterface(mDOMNode
));
271 if (!domElement
|| !content
)
274 if (!content
->GetDocument())
277 nsCOMPtr
<nsINameSpaceManager
> nameSpaceManager
=
278 do_GetService(NS_NAMESPACEMANAGER_CONTRACTID
);
282 for (index
= 0; index
< aNumAttribs
; index
++) {
283 aAttribValues
[index
] = nsnull
;
284 if (aAttribNames
[index
]) {
285 nsAutoString attributeValue
, nameSpaceURI
;
286 nsAutoString
attributeName(nsDependentString(static_cast<PRUnichar
*>(aAttribNames
[index
])));
289 if (aNameSpaceID
[index
]>0 &&
290 NS_SUCCEEDED(nameSpaceManager
->GetNameSpaceURI(aNameSpaceID
[index
], nameSpaceURI
)))
291 rv
= domElement
->GetAttributeNS(nameSpaceURI
, attributeName
, attributeValue
);
293 rv
= domElement
->GetAttribute(attributeName
, attributeValue
);
295 if (NS_SUCCEEDED(rv
))
296 aAttribValues
[index
] = ::SysAllocString(attributeValue
.get());
299 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
304 /* To do: use media type if not null */
305 STDMETHODIMP
nsAccessNodeWrap::get_computedStyle(
306 /* [in] */ unsigned short aMaxStyleProperties
,
307 /* [in] */ boolean aUseAlternateView
,
308 /* [length_is][size_is][out] */ BSTR __RPC_FAR
*aStyleProperties
,
309 /* [length_is][size_is][out] */ BSTR __RPC_FAR
*aStyleValues
,
310 /* [out] */ unsigned short __RPC_FAR
*aNumStyleProperties
)
313 *aNumStyleProperties
= 0;
318 nsCOMPtr
<nsIDOMCSSStyleDeclaration
> cssDecl
;
319 nsCoreUtils::GetComputedStyleDeclaration(EmptyString(), mDOMNode
,
320 getter_AddRefs(cssDecl
));
321 NS_ENSURE_TRUE(cssDecl
, E_FAIL
);
324 cssDecl
->GetLength(&length
);
326 PRUint32 index
, realIndex
;
327 for (index
= realIndex
= 0; index
< length
&& realIndex
< aMaxStyleProperties
; index
++) {
328 nsAutoString property
, value
;
329 if (NS_SUCCEEDED(cssDecl
->Item(index
, property
)) && property
.CharAt(0) != '-') // Ignore -moz-* properties
330 cssDecl
->GetPropertyValue(property
, value
); // Get property value
331 if (!value
.IsEmpty()) {
332 aStyleProperties
[realIndex
] = ::SysAllocString(property
.get());
333 aStyleValues
[realIndex
] = ::SysAllocString(value
.get());
337 *aNumStyleProperties
= static_cast<unsigned short>(realIndex
);
338 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
344 STDMETHODIMP
nsAccessNodeWrap::get_computedStyleForProperties(
345 /* [in] */ unsigned short aNumStyleProperties
,
346 /* [in] */ boolean aUseAlternateView
,
347 /* [length_is][size_is][in] */ BSTR __RPC_FAR
*aStyleProperties
,
348 /* [length_is][size_is][out] */ BSTR __RPC_FAR
*aStyleValues
)
354 nsCOMPtr
<nsIDOMCSSStyleDeclaration
> cssDecl
;
355 nsCoreUtils::GetComputedStyleDeclaration(EmptyString(), mDOMNode
,
356 getter_AddRefs(cssDecl
));
357 NS_ENSURE_TRUE(cssDecl
, E_FAIL
);
360 for (index
= 0; index
< aNumStyleProperties
; index
++) {
362 if (aStyleProperties
[index
])
363 cssDecl
->GetPropertyValue(nsDependentString(static_cast<PRUnichar
*>(aStyleProperties
[index
])), value
); // Get property value
364 aStyleValues
[index
] = ::SysAllocString(value
.get());
366 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
371 STDMETHODIMP
nsAccessNodeWrap::scrollTo(/* [in] */ boolean aScrollTopLeft
)
374 PRUint32 scrollType
=
375 aScrollTopLeft
? nsIAccessibleScrollType::SCROLL_TYPE_TOP_LEFT
:
376 nsIAccessibleScrollType::SCROLL_TYPE_BOTTOM_RIGHT
;
378 nsresult rv
= ScrollTo(scrollType
);
379 if (NS_SUCCEEDED(rv
))
381 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
386 ISimpleDOMNode
* nsAccessNodeWrap::MakeAccessNode(nsIDOMNode
*node
)
391 nsAccessNodeWrap
*newNode
= NULL
;
393 nsCOMPtr
<nsIContent
> content(do_QueryInterface(node
));
394 nsCOMPtr
<nsIDocument
> doc
;
397 doc
= content
->GetDocument();
399 // Get the document via QueryInterface, since there is no content node
400 doc
= do_QueryInterface(node
);
401 content
= do_QueryInterface(node
);
407 nsCOMPtr
<nsIAccessibilityService
> accService(do_GetService("@mozilla.org/accessibilityService;1"));
411 ISimpleDOMNode
*iNode
= NULL
;
412 nsCOMPtr
<nsIAccessible
> nsAcc
;
413 accService
->GetAccessibleInWeakShell(node
, mWeakShell
, getter_AddRefs(nsAcc
));
415 nsCOMPtr
<nsIAccessNode
> accessNode(do_QueryInterface(nsAcc
));
416 NS_ASSERTION(accessNode
, "nsIAccessible impl does not inherit from nsIAccessNode");
417 IAccessible
*msaaAccessible
;
418 nsAcc
->GetNativeInterface((void**)&msaaAccessible
); // addrefs
419 msaaAccessible
->QueryInterface(IID_ISimpleDOMNode
, (void**)&iNode
); // addrefs
420 msaaAccessible
->Release(); // Release IAccessible
423 newNode
= new nsAccessNodeWrap(node
, mWeakShell
);
428 iNode
= static_cast<ISimpleDOMNode
*>(newNode
);
436 STDMETHODIMP
nsAccessNodeWrap::get_parentNode(ISimpleDOMNode __RPC_FAR
*__RPC_FAR
*aNode
)
442 nsCOMPtr
<nsIDOMNode
> node
;
443 mDOMNode
->GetParentNode(getter_AddRefs(node
));
444 *aNode
= MakeAccessNode(node
);
445 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
450 STDMETHODIMP
nsAccessNodeWrap::get_firstChild(ISimpleDOMNode __RPC_FAR
*__RPC_FAR
*aNode
)
456 nsCOMPtr
<nsIDOMNode
> node
;
457 mDOMNode
->GetFirstChild(getter_AddRefs(node
));
458 *aNode
= MakeAccessNode(node
);
459 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
464 STDMETHODIMP
nsAccessNodeWrap::get_lastChild(ISimpleDOMNode __RPC_FAR
*__RPC_FAR
*aNode
)
470 nsCOMPtr
<nsIDOMNode
> node
;
471 mDOMNode
->GetLastChild(getter_AddRefs(node
));
472 *aNode
= MakeAccessNode(node
);
473 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
478 STDMETHODIMP
nsAccessNodeWrap::get_previousSibling(ISimpleDOMNode __RPC_FAR
*__RPC_FAR
*aNode
)
484 nsCOMPtr
<nsIDOMNode
> node
;
485 mDOMNode
->GetPreviousSibling(getter_AddRefs(node
));
486 *aNode
= MakeAccessNode(node
);
487 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
492 STDMETHODIMP
nsAccessNodeWrap::get_nextSibling(ISimpleDOMNode __RPC_FAR
*__RPC_FAR
*aNode
)
498 nsCOMPtr
<nsIDOMNode
> node
;
499 mDOMNode
->GetNextSibling(getter_AddRefs(node
));
500 *aNode
= MakeAccessNode(node
);
501 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
507 nsAccessNodeWrap::get_childAt(unsigned aChildIndex
,
508 ISimpleDOMNode __RPC_FAR
*__RPC_FAR
*aNode
)
513 nsCOMPtr
<nsIContent
> content(do_QueryInterface(mDOMNode
));
515 return E_FAIL
; // Node already shut down
517 nsCOMPtr
<nsIDOMNode
> node
=
518 do_QueryInterface(content
->GetChildAt(aChildIndex
));
521 return E_FAIL
; // No such child
523 *aNode
= MakeAccessNode(node
);
524 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
530 nsAccessNodeWrap::get_innerHTML(BSTR __RPC_FAR
*aInnerHTML
)
533 *aInnerHTML
= nsnull
;
535 nsCOMPtr
<nsIDOMNSHTMLElement
> domNSElement(do_QueryInterface(mDOMNode
));
537 return E_FAIL
; // Node already shut down
539 nsAutoString innerHTML
;
540 domNSElement
->GetInnerHTML(innerHTML
);
541 if (innerHTML
.IsEmpty())
544 *aInnerHTML
= ::SysAllocStringLen(innerHTML
.get(), innerHTML
.Length());
546 return E_OUTOFMEMORY
;
548 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
554 nsAccessNodeWrap::get_language(BSTR __RPC_FAR
*aLanguage
)
559 nsAutoString language
;
560 if (NS_FAILED(GetLanguage(language
))) {
564 if (language
.IsEmpty())
567 *aLanguage
= ::SysAllocStringLen(language
.get(), language
.Length());
569 return E_OUTOFMEMORY
;
571 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
577 nsAccessNodeWrap::get_localInterface(
578 /* [out] */ void __RPC_FAR
*__RPC_FAR
*localInterface
)
581 *localInterface
= static_cast<nsIAccessNode
*>(this);
583 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
587 void nsAccessNodeWrap::InitAccessibility()
589 if (gIsAccessibilityActive
) {
593 nsCOMPtr
<nsIPrefBranch
> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID
));
595 prefBranch
->GetBoolPref("accessibility.disableenumvariant", &gIsEnumVariantSupportDisabled
);
599 gmUserLib
=::LoadLibraryW(L
"USER32.DLL");
603 if (!gmNotifyWinEvent
)
604 gmNotifyWinEvent
= (LPFNNOTIFYWINEVENT
)GetProcAddress(gmUserLib
,"NotifyWinEvent");
605 if (!gmGetGUIThreadInfo
)
606 gmGetGUIThreadInfo
= (LPFNGETGUITHREADINFO
)GetProcAddress(gmUserLib
,"GetGUIThreadInfo");
609 DoATSpecificProcessing();
611 nsAccessNode::InitXPAccessibility();
614 void nsAccessNodeWrap::ShutdownAccessibility()
616 NS_IF_RELEASE(gTextEvent
);
619 if (!gIsAccessibilityActive
) {
623 nsAccessNode::ShutdownXPAccessibility();
626 int nsAccessNodeWrap::FilterA11yExceptions(unsigned int aCode
, EXCEPTION_POINTERS
*aExceptionInfo
)
628 if (aCode
== EXCEPTION_ACCESS_VIOLATION
) {
629 #ifdef MOZ_CRASHREPORTER
630 // MSAA swallows crashes (because it is COM-based)
631 // but we still need to learn about those crashes so we can fix them
632 // Make sure to pass them to the crash reporter
633 nsCOMPtr
<nsICrashReporter
> crashReporter
=
634 do_GetService("@mozilla.org/toolkit/crash-reporter;1");
636 crashReporter
->WriteMinidumpForException(aExceptionInfo
);
641 NS_NOTREACHED("We should only be catching crash exceptions");
643 return EXCEPTION_CONTINUE_SEARCH
;
647 GetHRESULT(nsresult aResult
)
653 case NS_ERROR_INVALID_ARG
: case NS_ERROR_INVALID_POINTER
:
656 case NS_ERROR_OUT_OF_MEMORY
:
657 return E_OUTOFMEMORY
;
659 case NS_ERROR_NOT_IMPLEMENTED
:
667 PRBool
nsAccessNodeWrap::IsOnlyMsaaCompatibleJawsPresent()
669 HMODULE jhookhandle
= ::GetModuleHandleW(L
"jhook");
671 return PR_FALSE
; // No JAWS, or some other screen reader, use IA2
673 PRUnichar fileName
[MAX_PATH
];
674 ::GetModuleFileNameW(jhookhandle
, fileName
, MAX_PATH
);
677 DWORD length
= ::GetFileVersionInfoSizeW(fileName
, &dummy
);
679 LPBYTE versionInfo
= new BYTE
[length
];
680 ::GetFileVersionInfoW(fileName
, 0, length
, versionInfo
);
683 VS_FIXEDFILEINFO
*fixedFileInfo
;
684 ::VerQueryValueW(versionInfo
, L
"\\", (LPVOID
*)&fixedFileInfo
, &uLen
);
685 DWORD dwFileVersionMS
= fixedFileInfo
->dwFileVersionMS
;
686 DWORD dwFileVersionLS
= fixedFileInfo
->dwFileVersionLS
;
687 delete [] versionInfo
;
689 DWORD dwLeftMost
= HIWORD(dwFileVersionMS
);
690 // DWORD dwSecondLeft = LOWORD(dwFileVersionMS);
691 DWORD dwSecondRight
= HIWORD(dwFileVersionLS
);
692 // DWORD dwRightMost = LOWORD(dwFileVersionLS);
694 return (dwLeftMost
< 8
695 || (dwLeftMost
== 8 && dwSecondRight
< 2173));
698 void nsAccessNodeWrap::TurnOffNewTabSwitchingForJawsAndWE()
700 HMODULE srHandle
= ::GetModuleHandleW(L
"jhook");
702 // No JAWS, try Window-Eyes
703 srHandle
= ::GetModuleHandleW(L
"gwm32inc");
705 // no screen reader we're interested in. Bail out.
710 // Check to see if the pref for disallowing CtrlTab is already set.
713 nsCOMPtr
<nsIPrefBranch
> prefs (do_GetService(NS_PREFSERVICE_CONTRACTID
));
715 PRBool hasDisallowNewCtrlTabPref
= PR_FALSE
;
716 nsresult rv
= prefs
->PrefHasUserValue(CTRLTAB_DISALLOW_FOR_SCREEN_READERS_PREF
,
717 &hasDisallowNewCtrlTabPref
);
718 if (NS_SUCCEEDED(rv
) && hasDisallowNewCtrlTabPref
) {
719 // This pref has been set before. There is no default for it.
720 // Do nothing further, respect the setting that's there.
721 // That way, if noone touches it, it'll stay on after toggled once.
722 // If someone decided to turn it off, we respect that, too.
726 // Value has never been set, set it.
727 prefs
->SetBoolPref(CTRLTAB_DISALLOW_FOR_SCREEN_READERS_PREF
, PR_TRUE
);
731 void nsAccessNodeWrap::DoATSpecificProcessing()
733 if (IsOnlyMsaaCompatibleJawsPresent())
734 // All versions below 8.0.2173 are not compatible
735 gIsIA2Disabled
= PR_TRUE
;
737 TurnOffNewTabSwitchingForJawsAndWE();