Back to index

lightning-sunbird  0.9+nobinonly
nsAccessNodeWrap.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 2003
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Original Author: Aaron Leventhal (aaronl@netscape.com)
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "nsAccessNodeWrap.h"
00040 #include "ISimpleDOMNode_i.c"
00041 #include "nsAccessibilityAtoms.h"
00042 #include "nsIAccessibilityService.h"
00043 #include "nsIAccessible.h"
00044 #include "nsIDocument.h"
00045 #include "nsIDOMCSSStyleDeclaration.h"
00046 #include "nsIDOMNodeList.h"
00047 #include "nsIDOMNSHTMLElement.h"
00048 #include "nsIDOMViewCSS.h"
00049 #include "nsIFrame.h"
00050 #include "nsINameSpaceManager.h"
00051 #include "nsIPrefService.h"
00052 #include "nsIPrefBranch.h"
00053 #include "nsIPresShell.h"
00054 #include "nsIScriptGlobalObject.h"
00055 #include "nsIServiceManager.h"
00056 #include "nsIServiceManager.h"
00057 
00059 HINSTANCE nsAccessNodeWrap::gmAccLib = nsnull;
00060 HINSTANCE nsAccessNodeWrap::gmUserLib = nsnull;
00061 LPFNACCESSIBLEOBJECTFROMWINDOW nsAccessNodeWrap::gmAccessibleObjectFromWindow = nsnull;
00062 LPFNNOTIFYWINEVENT nsAccessNodeWrap::gmNotifyWinEvent = nsnull;
00063 LPFNGETGUITHREADINFO nsAccessNodeWrap::gmGetGUIThreadInfo = nsnull;
00064 
00065 PRBool nsAccessNodeWrap::gIsEnumVariantSupportDisabled = 0;
00066 
00067 /* For documentation of the accessibility architecture, 
00068  * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
00069  */
00070 
00071 /*
00072  * Class nsAccessNodeWrap
00073  */
00074 
00075 //-----------------------------------------------------
00076 // construction 
00077 //-----------------------------------------------------
00078 
00079 nsAccessNodeWrap::nsAccessNodeWrap(nsIDOMNode *aNode, nsIWeakReference* aShell): 
00080   nsAccessNode(aNode, aShell)
00081 {
00082 }
00083 
00084 //-----------------------------------------------------
00085 // destruction
00086 //-----------------------------------------------------
00087 nsAccessNodeWrap::~nsAccessNodeWrap()
00088 {
00089 }
00090 
00091 
00092 //-----------------------------------------------------
00093 // IUnknown interface methods - see iunknown.h for documentation
00094 //-----------------------------------------------------
00095 
00096 STDMETHODIMP_(ULONG) nsAccessNodeWrap::AddRef()
00097 {
00098   return nsAccessNode::AddRef();
00099 }
00100 
00101 STDMETHODIMP_(ULONG) nsAccessNodeWrap::Release()
00102 {
00103   return nsAccessNode::Release();
00104 }
00105 
00106 STDMETHODIMP nsAccessNodeWrap::QueryInterface(REFIID iid, void** ppv)
00107 {
00108   *ppv = nsnull;
00109 
00110   if (IID_IUnknown == iid || IID_ISimpleDOMNode == iid)
00111     *ppv = NS_STATIC_CAST(ISimpleDOMNode*, this);
00112 
00113   if (nsnull == *ppv)
00114     return E_NOINTERFACE;      //iid not supported.
00115    
00116   (NS_REINTERPRET_CAST(IUnknown*, *ppv))->AddRef(); 
00117   return S_OK;
00118 }
00119 
00120 
00121 //-----------------------------------------------------
00122 // ISimpleDOMNode methods
00123 //-----------------------------------------------------
00124 
00125 STDMETHODIMP nsAccessNodeWrap::get_nodeInfo( 
00126     /* [out] */ BSTR __RPC_FAR *aNodeName,
00127     /* [out] */ short __RPC_FAR *aNameSpaceID,
00128     /* [out] */ BSTR __RPC_FAR *aNodeValue,
00129     /* [out] */ unsigned int __RPC_FAR *aNumChildren,
00130     /* [out] */ unsigned int __RPC_FAR *aUniqueID,
00131     /* [out] */ unsigned short __RPC_FAR *aNodeType)
00132 {
00133   if (!mDOMNode)
00134     return E_FAIL;
00135  
00136   *aNodeName = nsnull;
00137   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
00138 
00139   PRUint16 nodeType = 0;
00140   mDOMNode->GetNodeType(&nodeType);
00141   *aNodeType=NS_STATIC_CAST(unsigned short, nodeType);
00142 
00143   if (*aNodeType !=  NODETYPE_TEXT) {
00144     nsAutoString nodeName;
00145     mDOMNode->GetNodeName(nodeName);
00146     *aNodeName =   ::SysAllocString(nodeName.get());
00147   }
00148 
00149   nsAutoString nodeValue;
00150 
00151   mDOMNode->GetNodeValue(nodeValue);
00152   *aNodeValue = ::SysAllocString(nodeValue.get());
00153   *aNameSpaceID = content ? NS_STATIC_CAST(short, content->GetNameSpaceID()) : 0;
00154 
00155   // This is a unique ID for every content node.  The 3rd party
00156   // accessibility application can compare this to the childID we
00157   // return for events such as focus events, to correlate back to
00158   // data nodes in their internal object model.
00159   void *uniqueID;
00160   GetUniqueID(&uniqueID);
00161   *aUniqueID = - NS_PTR_TO_INT32(uniqueID);
00162 
00163   *aNumChildren = 0;
00164   PRUint32 numChildren = 0;
00165   nsCOMPtr<nsIDOMNodeList> nodeList;
00166   mDOMNode->GetChildNodes(getter_AddRefs(nodeList));
00167   if (nodeList && NS_OK == nodeList->GetLength(&numChildren))
00168     *aNumChildren = NS_STATIC_CAST(unsigned int, numChildren);
00169 
00170   return S_OK;
00171 }
00172 
00173 
00174        
00175 STDMETHODIMP nsAccessNodeWrap::get_attributes( 
00176     /* [in] */ unsigned short aMaxAttribs,
00177     /* [length_is][size_is][out] */ BSTR __RPC_FAR *aAttribNames,
00178     /* [length_is][size_is][out] */ short __RPC_FAR *aNameSpaceIDs,
00179     /* [length_is][size_is][out] */ BSTR __RPC_FAR *aAttribValues,
00180     /* [out] */ unsigned short __RPC_FAR *aNumAttribs)
00181 {
00182   *aNumAttribs = 0;
00183 
00184   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
00185   if (!content) 
00186     return E_FAIL;
00187 
00188   PRUint32 numAttribs = content->GetAttrCount();
00189 
00190   if (numAttribs > aMaxAttribs)
00191     numAttribs = aMaxAttribs;
00192   *aNumAttribs = NS_STATIC_CAST(unsigned short, numAttribs);
00193 
00194   PRInt32 nameSpaceID;
00195   nsCOMPtr<nsIAtom> nameAtom, prefixAtom;
00196 
00197   for (PRUint32 index = 0; index < numAttribs; index++) {
00198     aNameSpaceIDs[index] = 0; aAttribValues[index] = aAttribNames[index] = nsnull;
00199     nsAutoString attributeValue;
00200     const char *pszAttributeName; 
00201 
00202     if (NS_SUCCEEDED(content->GetAttrNameAt(index, &nameSpaceID, getter_AddRefs(nameAtom), getter_AddRefs(prefixAtom)))) {
00203       aNameSpaceIDs[index] = NS_STATIC_CAST(short, nameSpaceID);
00204       nameAtom->GetUTF8String(&pszAttributeName);
00205       aAttribNames[index] = ::SysAllocString(NS_ConvertUTF8toUCS2(pszAttributeName).get());
00206       if (NS_SUCCEEDED(content->GetAttr(nameSpaceID, nameAtom, attributeValue))) 
00207         aAttribValues[index] = ::SysAllocString(attributeValue.get());
00208     }
00209   }
00210 
00211   return S_OK; 
00212 }
00213         
00214 
00215 STDMETHODIMP nsAccessNodeWrap::get_attributesForNames( 
00216     /* [in] */ unsigned short aNumAttribs,
00217     /* [length_is][size_is][in] */ BSTR __RPC_FAR *aAttribNames,
00218     /* [length_is][size_is][in] */ short __RPC_FAR *aNameSpaceID,
00219     /* [length_is][size_is][retval] */ BSTR __RPC_FAR *aAttribValues)
00220 {
00221   nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(mDOMNode));
00222   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
00223 
00224   if (!domElement || !content) 
00225     return E_FAIL;
00226 
00227   if (!content->GetDocument())
00228     return E_FAIL;
00229 
00230   nsCOMPtr<nsINameSpaceManager> nameSpaceManager =
00231     do_GetService(NS_NAMESPACEMANAGER_CONTRACTID);
00232 
00233   PRInt32 index;
00234 
00235   for (index = 0; index < aNumAttribs; index++) {
00236     aAttribValues[index] = nsnull;
00237     if (aAttribNames[index]) {
00238       nsAutoString attributeValue, nameSpaceURI;
00239       nsAutoString attributeName(nsDependentString(NS_STATIC_CAST(PRUnichar*,aAttribNames[index])));
00240       nsresult rv;
00241 
00242       if (aNameSpaceID[index]>0 && 
00243         NS_SUCCEEDED(nameSpaceManager->GetNameSpaceURI(aNameSpaceID[index], nameSpaceURI)))
00244           rv = domElement->GetAttributeNS(nameSpaceURI, attributeName, attributeValue);
00245       else 
00246         rv = domElement->GetAttribute(attributeName, attributeValue);
00247 
00248       if (NS_SUCCEEDED(rv))
00249         aAttribValues[index] = ::SysAllocString(attributeValue.get());
00250     }
00251   }
00252 
00253   return S_OK; 
00254 }
00255 
00256 
00257 NS_IMETHODIMP nsAccessNodeWrap::GetComputedStyleDeclaration(nsIDOMCSSStyleDeclaration **aCssDecl, PRUint32 *aLength)
00258 {
00259   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
00260   if (!content) 
00261     return NS_ERROR_FAILURE;   
00262 
00263   if (content->IsContentOfType(nsIContent::eTEXT)) {
00264     content = content->GetParent();
00265     NS_ASSERTION(content, "No parent for text node");
00266   }
00267 
00268   nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(content));
00269   nsCOMPtr<nsIDocument> doc = content->GetDocument();
00270 
00271   if (!domElement || !doc) {
00272     return NS_ERROR_FAILURE;
00273   }
00274 
00275   nsCOMPtr<nsIDOMViewCSS> viewCSS(do_QueryInterface(doc->GetScriptGlobalObject()));
00276 
00277   if (!viewCSS)
00278     return NS_ERROR_FAILURE;   
00279 
00280   nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl;
00281   nsAutoString empty;
00282   viewCSS->GetComputedStyle(domElement, empty, getter_AddRefs(cssDecl));
00283   if (cssDecl) {
00284     *aCssDecl = cssDecl;
00285     NS_ADDREF(*aCssDecl);
00286     cssDecl->GetLength(aLength);
00287     return NS_OK;
00288   }
00289   return NS_ERROR_FAILURE;
00290 }
00291 
00292 /* To do: use media type if not null */
00293 STDMETHODIMP nsAccessNodeWrap::get_computedStyle( 
00294     /* [in] */ unsigned short aMaxStyleProperties,
00295     /* [in] */ boolean aUseAlternateView,
00296     /* [length_is][size_is][out] */ BSTR __RPC_FAR *aStyleProperties,
00297     /* [length_is][size_is][out] */ BSTR __RPC_FAR *aStyleValues,
00298     /* [out] */ unsigned short __RPC_FAR *aNumStyleProperties)
00299 {
00300   if (!mDOMNode)
00301     return E_FAIL;
00302  
00303   *aNumStyleProperties = 0;
00304   PRUint32 length;
00305   nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl;
00306   if (NS_FAILED(GetComputedStyleDeclaration(getter_AddRefs(cssDecl), &length)))
00307     return E_FAIL;
00308 
00309   PRUint32 index, realIndex;
00310   for (index = realIndex = 0; index < length && realIndex < aMaxStyleProperties; index ++) {
00311     nsAutoString property, value;
00312     if (NS_SUCCEEDED(cssDecl->Item(index, property)) && property.CharAt(0) != '-')  // Ignore -moz-* properties
00313       cssDecl->GetPropertyValue(property, value);  // Get property value
00314     if (!value.IsEmpty()) {
00315       aStyleProperties[realIndex] =   ::SysAllocString(property.get());
00316       aStyleValues[realIndex]     =   ::SysAllocString(value.get());
00317       ++realIndex;
00318     }
00319   }
00320   *aNumStyleProperties = NS_STATIC_CAST(unsigned short, realIndex);
00321 
00322   return S_OK;
00323 }
00324 
00325 
00326 STDMETHODIMP nsAccessNodeWrap::get_computedStyleForProperties( 
00327     /* [in] */ unsigned short aNumStyleProperties,
00328     /* [in] */ boolean aUseAlternateView,
00329     /* [length_is][size_is][in] */ BSTR __RPC_FAR *aStyleProperties,
00330     /* [length_is][size_is][out] */ BSTR __RPC_FAR *aStyleValues)
00331 {
00332   if (!mDOMNode)
00333     return E_FAIL;
00334  
00335   PRUint32 length = 0;
00336   nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl;
00337   nsresult rv = GetComputedStyleDeclaration(getter_AddRefs(cssDecl), &length);
00338   if (NS_FAILED(rv))
00339     return E_FAIL;
00340 
00341   PRUint32 index;
00342   for (index = 0; index < aNumStyleProperties; index ++) {
00343     nsAutoString value;
00344     if (aStyleProperties[index])
00345       cssDecl->GetPropertyValue(nsDependentString(NS_STATIC_CAST(PRUnichar*,aStyleProperties[index])), value);  // Get property value
00346     aStyleValues[index] = ::SysAllocString(value.get());
00347   }
00348 
00349   return S_OK;
00350 }
00351 
00352 STDMETHODIMP nsAccessNodeWrap::scrollTo(/* [in] */ boolean aScrollTopLeft)
00353 {
00354   nsCOMPtr<nsIPresShell> shell(GetPresShell());
00355   if (!mDOMNode || !shell) {
00356     return E_FAIL;
00357   }
00358 
00359   nsIFrame *frame = GetFrame();
00360 
00361   if (frame) {
00362     PRInt32 percent = NS_PRESSHELL_SCROLL_ANYWHERE;
00363     if (aScrollTopLeft)
00364       percent = 0;
00365     return shell->ScrollFrameIntoView(frame, percent, percent);
00366   }
00367 
00368   return E_FAIL;
00369 }
00370 
00371 
00372 ISimpleDOMNode* nsAccessNodeWrap::MakeAccessNode(nsIDOMNode *node)
00373 {
00374   if (!node) 
00375     return NULL;
00376 
00377   nsAccessNodeWrap *newNode = NULL;
00378   
00379   nsCOMPtr<nsIContent> content(do_QueryInterface(node));
00380   nsCOMPtr<nsIDocument> doc;
00381 
00382   if (content) 
00383     doc = content->GetDocument();
00384   else {
00385     // Get the document via QueryInterface, since there is no content node
00386     doc = do_QueryInterface(node);
00387     content = do_QueryInterface(node);
00388   }
00389 
00390   if (!doc)
00391     return NULL;
00392 
00393   nsCOMPtr<nsIAccessibilityService> accService(do_GetService("@mozilla.org/accessibilityService;1"));
00394   if (!accService)
00395     return NULL;
00396 
00397   ISimpleDOMNode *iNode = NULL;
00398   nsCOMPtr<nsIAccessible> nsAcc;
00399   accService->GetAccessibleInWeakShell(node, mWeakShell, getter_AddRefs(nsAcc));
00400   if (nsAcc) {
00401     nsCOMPtr<nsIAccessNode> accessNode(do_QueryInterface(nsAcc));
00402     NS_ASSERTION(accessNode, "nsIAccessible impl does not inherit from nsIAccessNode");
00403     IAccessible *msaaAccessible;
00404     nsAcc->GetNativeInterface((void**)&msaaAccessible); // addrefs
00405     msaaAccessible->QueryInterface(IID_ISimpleDOMNode, (void**)&iNode); // addrefs
00406     msaaAccessible->Release(); // Release IAccessible
00407   }
00408   else {
00409     newNode = new nsAccessNodeWrap(node, mWeakShell);
00410     if (!newNode)
00411       return NULL;
00412 
00413     newNode->Init();
00414     iNode = NS_STATIC_CAST(ISimpleDOMNode*, newNode);
00415     iNode->AddRef();
00416   }
00417 
00418   return iNode;
00419 }
00420 
00421 
00422 STDMETHODIMP nsAccessNodeWrap::get_parentNode(ISimpleDOMNode __RPC_FAR *__RPC_FAR *aNode)
00423 {
00424   if (!mDOMNode)
00425     return E_FAIL;
00426  
00427   nsCOMPtr<nsIDOMNode> node;
00428   mDOMNode->GetParentNode(getter_AddRefs(node));
00429   *aNode = MakeAccessNode(node);
00430 
00431   return S_OK;
00432 }
00433 
00434 STDMETHODIMP nsAccessNodeWrap::get_firstChild(ISimpleDOMNode __RPC_FAR *__RPC_FAR *aNode)
00435 {
00436   if (!mDOMNode)
00437     return E_FAIL;
00438  
00439   nsCOMPtr<nsIDOMNode> node;
00440   mDOMNode->GetFirstChild(getter_AddRefs(node));
00441   *aNode = MakeAccessNode(node);
00442 
00443   return S_OK;
00444 }
00445 
00446 STDMETHODIMP nsAccessNodeWrap::get_lastChild(ISimpleDOMNode __RPC_FAR *__RPC_FAR *aNode)
00447 {
00448   if (!mDOMNode)
00449     return E_FAIL;
00450 
00451   nsCOMPtr<nsIDOMNode> node;
00452   mDOMNode->GetLastChild(getter_AddRefs(node));
00453   *aNode = MakeAccessNode(node);
00454 
00455   return S_OK;
00456 }
00457 
00458 STDMETHODIMP nsAccessNodeWrap::get_previousSibling(ISimpleDOMNode __RPC_FAR *__RPC_FAR *aNode)
00459 {
00460   if (!mDOMNode)
00461     return E_FAIL;
00462 
00463   nsCOMPtr<nsIDOMNode> node;
00464   mDOMNode->GetPreviousSibling(getter_AddRefs(node));
00465   *aNode = MakeAccessNode(node);
00466 
00467   return S_OK;
00468 }
00469 
00470 STDMETHODIMP nsAccessNodeWrap::get_nextSibling(ISimpleDOMNode __RPC_FAR *__RPC_FAR *aNode)
00471 {
00472   if (!mDOMNode)
00473     return E_FAIL;
00474 
00475   nsCOMPtr<nsIDOMNode> node;
00476   mDOMNode->GetNextSibling(getter_AddRefs(node));
00477   *aNode = MakeAccessNode(node);
00478 
00479   return S_OK;
00480 }
00481 
00482 STDMETHODIMP 
00483 nsAccessNodeWrap::get_childAt(unsigned aChildIndex,
00484                               ISimpleDOMNode __RPC_FAR *__RPC_FAR *aNode)
00485 {
00486   *aNode = nsnull;
00487 
00488   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
00489   if (!content)
00490     return E_FAIL;  // Node already shut down
00491 
00492   nsCOMPtr<nsIDOMNode> node =
00493     do_QueryInterface(content->GetChildAt(aChildIndex));
00494 
00495   if (!node)
00496     return E_FAIL; // No such child
00497 
00498   *aNode = MakeAccessNode(node);
00499 
00500   return S_OK;
00501 }
00502 
00503 STDMETHODIMP 
00504 nsAccessNodeWrap::get_innerHTML(BSTR __RPC_FAR *aInnerHTML)
00505 {
00506   *aInnerHTML = nsnull;
00507 
00508   nsCOMPtr<nsIDOMNSHTMLElement> domNSElement(do_QueryInterface(mDOMNode));
00509   if (!domNSElement)
00510     return E_FAIL; // Node already shut down
00511 
00512   nsAutoString innerHTML;
00513   domNSElement->GetInnerHTML(innerHTML);
00514   *aInnerHTML = ::SysAllocString(innerHTML.get());
00515 
00516   return S_OK;
00517 }
00518 
00519 STDMETHODIMP 
00520 nsAccessNodeWrap::get_language(BSTR __RPC_FAR *aLanguage)
00521 {
00522   *aLanguage = nsnull;
00523   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
00524   if (!content) {
00525     return E_FAIL;
00526   }
00527 
00528   nsAutoString language;
00529   for (nsIContent *walkUp = content; walkUp = walkUp->GetParent(); walkUp) {
00530     if (NS_CONTENT_ATTR_HAS_VALUE ==
00531         walkUp->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::lang, language)) {
00532       break;
00533     }
00534   }
00535 
00536   if (language.IsEmpty()) { // Nothing found, so use document's language
00537     nsIDocument *doc = content->GetOwnerDoc();
00538     if (doc) {
00539       doc->GetHeaderData(nsAccessibilityAtoms::headerContentLanguage, language);
00540     }
00541   }
00542  
00543   *aLanguage = ::SysAllocString(language.get());
00544   return S_OK;
00545 }
00546 
00547 STDMETHODIMP 
00548 nsAccessNodeWrap::get_localInterface( 
00549     /* [out] */ void __RPC_FAR *__RPC_FAR *localInterface)
00550 {
00551   *localInterface = NS_STATIC_CAST(nsIAccessNode*, this);
00552   NS_ADDREF_THIS();
00553   return S_OK;
00554 }
00555  
00556 void nsAccessNodeWrap::InitAccessibility()
00557 {
00558   if (gIsAccessibilityActive) {
00559     return;
00560   }
00561 
00562   nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID));
00563   if (prefBranch) {
00564     prefBranch->GetBoolPref("accessibility.disableenumvariant", &gIsEnumVariantSupportDisabled);
00565   }
00566 
00567   if (!gmUserLib) {
00568     gmUserLib =::LoadLibrary("USER32.DLL");
00569   }
00570 
00571   if (gmUserLib) {
00572     if (!gmNotifyWinEvent)
00573       gmNotifyWinEvent = (LPFNNOTIFYWINEVENT)GetProcAddress(gmUserLib,"NotifyWinEvent");
00574     if (!gmGetGUIThreadInfo)
00575       gmGetGUIThreadInfo = (LPFNGETGUITHREADINFO)GetProcAddress(gmUserLib,"GetGUIThreadInfo");
00576   }
00577 
00578   nsAccessNode::InitXPAccessibility();
00579 }
00580 
00581 void nsAccessNodeWrap::ShutdownAccessibility()
00582 {
00583   if (!gIsAccessibilityActive) {
00584     return;
00585   }
00586 
00587   nsAccessNode::ShutdownXPAccessibility();
00588 }