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 GetComputedStyleDeclaration(EmptyString(), mDOMNode
, getter_AddRefs(cssDecl
));
320 NS_ENSURE_TRUE(cssDecl
, E_FAIL
);
323 cssDecl
->GetLength(&length
);
325 PRUint32 index
, realIndex
;
326 for (index
= realIndex
= 0; index
< length
&& realIndex
< aMaxStyleProperties
; index
++) {
327 nsAutoString property
, value
;
328 if (NS_SUCCEEDED(cssDecl
->Item(index
, property
)) && property
.CharAt(0) != '-') // Ignore -moz-* properties
329 cssDecl
->GetPropertyValue(property
, value
); // Get property value
330 if (!value
.IsEmpty()) {
331 aStyleProperties
[realIndex
] = ::SysAllocString(property
.get());
332 aStyleValues
[realIndex
] = ::SysAllocString(value
.get());
336 *aNumStyleProperties
= static_cast<unsigned short>(realIndex
);
337 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
343 STDMETHODIMP
nsAccessNodeWrap::get_computedStyleForProperties(
344 /* [in] */ unsigned short aNumStyleProperties
,
345 /* [in] */ boolean aUseAlternateView
,
346 /* [length_is][size_is][in] */ BSTR __RPC_FAR
*aStyleProperties
,
347 /* [length_is][size_is][out] */ BSTR __RPC_FAR
*aStyleValues
)
353 nsCOMPtr
<nsIDOMCSSStyleDeclaration
> cssDecl
;
354 GetComputedStyleDeclaration(EmptyString(), mDOMNode
, getter_AddRefs(cssDecl
));
355 NS_ENSURE_TRUE(cssDecl
, E_FAIL
);
358 for (index
= 0; index
< aNumStyleProperties
; index
++) {
360 if (aStyleProperties
[index
])
361 cssDecl
->GetPropertyValue(nsDependentString(static_cast<PRUnichar
*>(aStyleProperties
[index
])), value
); // Get property value
362 aStyleValues
[index
] = ::SysAllocString(value
.get());
364 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
369 STDMETHODIMP
nsAccessNodeWrap::scrollTo(/* [in] */ boolean aScrollTopLeft
)
372 PRUint32 scrollType
=
373 aScrollTopLeft
? nsIAccessibleScrollType::SCROLL_TYPE_TOP_LEFT
:
374 nsIAccessibleScrollType::SCROLL_TYPE_BOTTOM_RIGHT
;
376 nsresult rv
= ScrollTo(scrollType
);
377 if (NS_SUCCEEDED(rv
))
379 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
384 ISimpleDOMNode
* nsAccessNodeWrap::MakeAccessNode(nsIDOMNode
*node
)
389 nsAccessNodeWrap
*newNode
= NULL
;
391 nsCOMPtr
<nsIContent
> content(do_QueryInterface(node
));
392 nsCOMPtr
<nsIDocument
> doc
;
395 doc
= content
->GetDocument();
397 // Get the document via QueryInterface, since there is no content node
398 doc
= do_QueryInterface(node
);
399 content
= do_QueryInterface(node
);
405 nsCOMPtr
<nsIAccessibilityService
> accService(do_GetService("@mozilla.org/accessibilityService;1"));
409 ISimpleDOMNode
*iNode
= NULL
;
410 nsCOMPtr
<nsIAccessible
> nsAcc
;
411 accService
->GetAccessibleInWeakShell(node
, mWeakShell
, getter_AddRefs(nsAcc
));
413 nsCOMPtr
<nsIAccessNode
> accessNode(do_QueryInterface(nsAcc
));
414 NS_ASSERTION(accessNode
, "nsIAccessible impl does not inherit from nsIAccessNode");
415 IAccessible
*msaaAccessible
;
416 nsAcc
->GetNativeInterface((void**)&msaaAccessible
); // addrefs
417 msaaAccessible
->QueryInterface(IID_ISimpleDOMNode
, (void**)&iNode
); // addrefs
418 msaaAccessible
->Release(); // Release IAccessible
421 newNode
= new nsAccessNodeWrap(node
, mWeakShell
);
426 iNode
= static_cast<ISimpleDOMNode
*>(newNode
);
434 STDMETHODIMP
nsAccessNodeWrap::get_parentNode(ISimpleDOMNode __RPC_FAR
*__RPC_FAR
*aNode
)
440 nsCOMPtr
<nsIDOMNode
> node
;
441 mDOMNode
->GetParentNode(getter_AddRefs(node
));
442 *aNode
= MakeAccessNode(node
);
443 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
448 STDMETHODIMP
nsAccessNodeWrap::get_firstChild(ISimpleDOMNode __RPC_FAR
*__RPC_FAR
*aNode
)
454 nsCOMPtr
<nsIDOMNode
> node
;
455 mDOMNode
->GetFirstChild(getter_AddRefs(node
));
456 *aNode
= MakeAccessNode(node
);
457 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
462 STDMETHODIMP
nsAccessNodeWrap::get_lastChild(ISimpleDOMNode __RPC_FAR
*__RPC_FAR
*aNode
)
468 nsCOMPtr
<nsIDOMNode
> node
;
469 mDOMNode
->GetLastChild(getter_AddRefs(node
));
470 *aNode
= MakeAccessNode(node
);
471 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
476 STDMETHODIMP
nsAccessNodeWrap::get_previousSibling(ISimpleDOMNode __RPC_FAR
*__RPC_FAR
*aNode
)
482 nsCOMPtr
<nsIDOMNode
> node
;
483 mDOMNode
->GetPreviousSibling(getter_AddRefs(node
));
484 *aNode
= MakeAccessNode(node
);
485 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
490 STDMETHODIMP
nsAccessNodeWrap::get_nextSibling(ISimpleDOMNode __RPC_FAR
*__RPC_FAR
*aNode
)
496 nsCOMPtr
<nsIDOMNode
> node
;
497 mDOMNode
->GetNextSibling(getter_AddRefs(node
));
498 *aNode
= MakeAccessNode(node
);
499 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
505 nsAccessNodeWrap::get_childAt(unsigned aChildIndex
,
506 ISimpleDOMNode __RPC_FAR
*__RPC_FAR
*aNode
)
511 nsCOMPtr
<nsIContent
> content(do_QueryInterface(mDOMNode
));
513 return E_FAIL
; // Node already shut down
515 nsCOMPtr
<nsIDOMNode
> node
=
516 do_QueryInterface(content
->GetChildAt(aChildIndex
));
519 return E_FAIL
; // No such child
521 *aNode
= MakeAccessNode(node
);
522 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
528 nsAccessNodeWrap::get_innerHTML(BSTR __RPC_FAR
*aInnerHTML
)
531 *aInnerHTML
= nsnull
;
533 nsCOMPtr
<nsIDOMNSHTMLElement
> domNSElement(do_QueryInterface(mDOMNode
));
535 return E_FAIL
; // Node already shut down
537 nsAutoString innerHTML
;
538 domNSElement
->GetInnerHTML(innerHTML
);
539 if (innerHTML
.IsEmpty())
542 *aInnerHTML
= ::SysAllocStringLen(innerHTML
.get(), innerHTML
.Length());
544 return E_OUTOFMEMORY
;
546 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
552 nsAccessNodeWrap::get_language(BSTR __RPC_FAR
*aLanguage
)
557 nsAutoString language
;
558 if (NS_FAILED(GetLanguage(language
))) {
562 if (language
.IsEmpty())
565 *aLanguage
= ::SysAllocStringLen(language
.get(), language
.Length());
567 return E_OUTOFMEMORY
;
569 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
575 nsAccessNodeWrap::get_localInterface(
576 /* [out] */ void __RPC_FAR
*__RPC_FAR
*localInterface
)
579 *localInterface
= static_cast<nsIAccessNode
*>(this);
581 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
585 void nsAccessNodeWrap::InitAccessibility()
587 if (gIsAccessibilityActive
) {
591 nsCOMPtr
<nsIPrefBranch
> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID
));
593 prefBranch
->GetBoolPref("accessibility.disableenumvariant", &gIsEnumVariantSupportDisabled
);
597 gmUserLib
=::LoadLibraryW(L
"USER32.DLL");
601 if (!gmNotifyWinEvent
)
602 gmNotifyWinEvent
= (LPFNNOTIFYWINEVENT
)GetProcAddress(gmUserLib
,"NotifyWinEvent");
603 if (!gmGetGUIThreadInfo
)
604 gmGetGUIThreadInfo
= (LPFNGETGUITHREADINFO
)GetProcAddress(gmUserLib
,"GetGUIThreadInfo");
607 DoATSpecificProcessing();
609 nsAccessNode::InitXPAccessibility();
612 void nsAccessNodeWrap::ShutdownAccessibility()
614 NS_IF_RELEASE(gTextEvent
);
617 if (!gIsAccessibilityActive
) {
621 nsAccessNode::ShutdownXPAccessibility();
624 int nsAccessNodeWrap::FilterA11yExceptions(unsigned int aCode
, EXCEPTION_POINTERS
*aExceptionInfo
)
626 if (aCode
== EXCEPTION_ACCESS_VIOLATION
) {
627 #ifdef MOZ_CRASHREPORTER
628 // MSAA swallows crashes (because it is COM-based)
629 // but we still need to learn about those crashes so we can fix them
630 // Make sure to pass them to the crash reporter
631 nsCOMPtr
<nsICrashReporter
> crashReporter
=
632 do_GetService("@mozilla.org/toolkit/crash-reporter;1");
634 crashReporter
->WriteMinidumpForException(aExceptionInfo
);
639 NS_NOTREACHED("We should only be catching crash exceptions");
641 return EXCEPTION_CONTINUE_SEARCH
;
645 GetHRESULT(nsresult aResult
)
651 case NS_ERROR_INVALID_ARG
: case NS_ERROR_INVALID_POINTER
:
654 case NS_ERROR_OUT_OF_MEMORY
:
655 return E_OUTOFMEMORY
;
657 case NS_ERROR_NOT_IMPLEMENTED
:
665 PRBool
nsAccessNodeWrap::IsOnlyMsaaCompatibleJawsPresent()
667 HMODULE jhookhandle
= ::GetModuleHandleW(L
"jhook");
669 return PR_FALSE
; // No JAWS, or some other screen reader, use IA2
671 PRUnichar fileName
[MAX_PATH
];
672 ::GetModuleFileNameW(jhookhandle
, fileName
, MAX_PATH
);
675 DWORD length
= ::GetFileVersionInfoSizeW(fileName
, &dummy
);
677 LPBYTE versionInfo
= new BYTE
[length
];
678 ::GetFileVersionInfoW(fileName
, 0, length
, versionInfo
);
681 VS_FIXEDFILEINFO
*fixedFileInfo
;
682 ::VerQueryValueW(versionInfo
, L
"\\", (LPVOID
*)&fixedFileInfo
, &uLen
);
683 DWORD dwFileVersionMS
= fixedFileInfo
->dwFileVersionMS
;
684 DWORD dwFileVersionLS
= fixedFileInfo
->dwFileVersionLS
;
685 delete [] versionInfo
;
687 DWORD dwLeftMost
= HIWORD(dwFileVersionMS
);
688 // DWORD dwSecondLeft = LOWORD(dwFileVersionMS);
689 DWORD dwSecondRight
= HIWORD(dwFileVersionLS
);
690 // DWORD dwRightMost = LOWORD(dwFileVersionLS);
692 return (dwLeftMost
< 8
693 || (dwLeftMost
== 8 && dwSecondRight
< 2173));
696 void nsAccessNodeWrap::TurnOffNewTabSwitchingForJawsAndWE()
698 HMODULE srHandle
= ::GetModuleHandleW(L
"jhook");
700 // No JAWS, try Window-Eyes
701 srHandle
= ::GetModuleHandleW(L
"gwm32inc");
703 // no screen reader we're interested in. Bail out.
708 // Check to see if the pref for disallowing CtrlTab is already set.
711 nsCOMPtr
<nsIPrefBranch
> prefs (do_GetService(NS_PREFSERVICE_CONTRACTID
));
713 PRBool hasDisallowNewCtrlTabPref
= PR_FALSE
;
714 nsresult rv
= prefs
->PrefHasUserValue(CTRLTAB_DISALLOW_FOR_SCREEN_READERS_PREF
,
715 &hasDisallowNewCtrlTabPref
);
716 if (NS_SUCCEEDED(rv
) && hasDisallowNewCtrlTabPref
) {
717 // This pref has been set before. There is no default for it.
718 // Do nothing further, respect the setting that's there.
719 // That way, if noone touches it, it'll stay on after toggled once.
720 // If someone decided to turn it off, we respect that, too.
724 // Value has never been set, set it.
725 prefs
->SetBoolPref(CTRLTAB_DISALLOW_FOR_SCREEN_READERS_PREF
, PR_TRUE
);
729 void nsAccessNodeWrap::DoATSpecificProcessing()
731 if (IsOnlyMsaaCompatibleJawsPresent())
732 // All versions below 8.0.2173 are not compatible
733 gIsIA2Disabled
= PR_TRUE
;
735 TurnOffNewTabSwitchingForJawsAndWE();