Home | History | Annotate | Download | only in win
      1 /*
      2  * Copyright (C) 2008, 2009, 2010 Apple Inc. All Rights Reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 
     27 #include "config.h"
     28 #include "AXObjectCache.h"
     29 
     30 #include "AccessibilityObject.h"
     31 #include "Chrome.h"
     32 #include "Document.h"
     33 #include "Page.h"
     34 #include "RenderObject.h"
     35 
     36 using namespace std;
     37 
     38 namespace WebCore {
     39 
     40 void AXObjectCache::detachWrapper(AccessibilityObject* obj)
     41 {
     42     // On Windows, AccessibilityObjects are created when get_accChildCount is
     43     // called, but they are not wrapped until get_accChild is called, so this
     44     // object may not have a wrapper.
     45     if (AccessibilityObjectWrapper* wrapper = obj->wrapper())
     46         wrapper->detach();
     47 }
     48 
     49 void AXObjectCache::attachWrapper(AccessibilityObject*)
     50 {
     51     // On Windows, AccessibilityObjects are wrapped when the accessibility
     52     // software requests them via get_accChild.
     53 }
     54 
     55 void AXObjectCache::handleScrolledToAnchor(const Node* anchorNode)
     56 {
     57     // The anchor node may not be accessible. Post the notification for the
     58     // first accessible object.
     59     postPlatformNotification(AccessibilityObject::firstAccessibleObjectFromNode(anchorNode), AXScrolledToAnchor);
     60 }
     61 
     62 void AXObjectCache::postPlatformNotification(AccessibilityObject* obj, AXNotification notification)
     63 {
     64     if (!obj)
     65         return;
     66 
     67     Document* document = obj->document();
     68     if (!document)
     69         return;
     70 
     71     Page* page = document->page();
     72     if (!page || !page->chrome()->platformPageClient())
     73         return;
     74 
     75     DWORD msaaEvent;
     76     switch (notification) {
     77         case AXFocusedUIElementChanged:
     78         case AXActiveDescendantChanged:
     79             msaaEvent = EVENT_OBJECT_FOCUS;
     80             break;
     81 
     82         case AXScrolledToAnchor:
     83             msaaEvent = EVENT_SYSTEM_SCROLLINGSTART;
     84             break;
     85 
     86         case AXValueChanged:
     87         case AXMenuListValueChanged:
     88             msaaEvent = EVENT_OBJECT_VALUECHANGE;
     89             break;
     90 
     91         default:
     92             return;
     93     }
     94 
     95     // Windows will end up calling get_accChild() on the root accessible
     96     // object for the WebView, passing the child ID that we specify below. We
     97     // negate the AXID so we know that the caller is passing the ID of an
     98     // element, not the index of a child element.
     99 
    100     ASSERT(obj->axObjectID() >= 1);
    101     ASSERT(obj->axObjectID() <= numeric_limits<LONG>::max());
    102 
    103     NotifyWinEvent(msaaEvent, page->chrome()->platformPageClient(), OBJID_CLIENT, -static_cast<LONG>(obj->axObjectID()));
    104 }
    105 
    106 AXID AXObjectCache::platformGenerateAXID() const
    107 {
    108     static AXID lastUsedID = 0;
    109 
    110     // Generate a new ID. Windows accessibility relies on a positive AXID,
    111     // ranging from 1 to LONG_MAX.
    112     AXID objID = lastUsedID;
    113     do {
    114         ++objID;
    115         objID %= std::numeric_limits<LONG>::max();
    116     } while (objID == 0 || HashTraits<AXID>::isDeletedValue(objID) || m_idsInUse.contains(objID));
    117 
    118     ASSERT(objID >= 1 && objID <= std::numeric_limits<LONG>::max());
    119 
    120     lastUsedID = objID;
    121 
    122     return objID;
    123 }
    124 
    125 void AXObjectCache::handleFocusedUIElementChanged(RenderObject*, RenderObject* newFocusedRenderer)
    126 {
    127     if (!newFocusedRenderer)
    128         return;
    129 
    130     Page* page = newFocusedRenderer->document()->page();
    131     if (!page || !page->chrome()->platformPageClient())
    132         return;
    133 
    134     AccessibilityObject* focusedObject = focusedUIElementForPage(page);
    135     if (!focusedObject)
    136         return;
    137 
    138     ASSERT(!focusedObject->accessibilityIsIgnored());
    139 
    140     postPlatformNotification(focusedObject, AXFocusedUIElementChanged);
    141 }
    142 
    143 } // namespace WebCore
    144