forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			162 lines
		
	
	
	
		
			4.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			162 lines
		
	
	
	
		
			4.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- 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 "InterfaceInitFuncs.h"
 | |
| 
 | |
| #include "LocalAccessible-inl.h"
 | |
| #include "AccessibleWrap.h"
 | |
| #include "nsAccUtils.h"
 | |
| #include "nsMai.h"
 | |
| #include "mozilla/Likely.h"
 | |
| #include "mozilla/a11y/DocAccessibleParent.h"
 | |
| #include "mozilla/a11y/RemoteAccessible.h"
 | |
| #include "mozilla/dom/BrowserParent.h"
 | |
| 
 | |
| using namespace mozilla::a11y;
 | |
| 
 | |
| extern "C" {
 | |
| 
 | |
| static AtkObject* refAccessibleAtPointCB(AtkComponent* aComponent, gint aAccX,
 | |
|                                          gint aAccY, AtkCoordType aCoordType) {
 | |
|   return refAccessibleAtPointHelper(ATK_OBJECT(aComponent), aAccX, aAccY,
 | |
|                                     aCoordType);
 | |
| }
 | |
| 
 | |
| static void getExtentsCB(AtkComponent* aComponent, gint* aX, gint* aY,
 | |
|                          gint* aWidth, gint* aHeight, AtkCoordType aCoordType) {
 | |
|   getExtentsHelper(ATK_OBJECT(aComponent), aX, aY, aWidth, aHeight, aCoordType);
 | |
| }
 | |
| 
 | |
| static gboolean grabFocusCB(AtkComponent* aComponent) {
 | |
|   AtkObject* atkObject = ATK_OBJECT(aComponent);
 | |
|   Accessible* acc = GetInternalObj(atkObject);
 | |
|   if (acc) {
 | |
|     acc->TakeFocus();
 | |
|     return TRUE;
 | |
|   }
 | |
|   return FALSE;
 | |
| }
 | |
| 
 | |
| // ScrollType is compatible
 | |
| MOZ_CAN_RUN_SCRIPT_BOUNDARY
 | |
| static gboolean scrollToCB(AtkComponent* aComponent, AtkScrollType type) {
 | |
|   AtkObject* atkObject = ATK_OBJECT(aComponent);
 | |
|   if (Accessible* acc = GetInternalObj(atkObject)) {
 | |
|     acc->ScrollTo(type);
 | |
|     return TRUE;
 | |
|   }
 | |
| 
 | |
|   return FALSE;
 | |
| }
 | |
| 
 | |
| // CoordType is compatible
 | |
| static gboolean scrollToPointCB(AtkComponent* aComponent, AtkCoordType coords,
 | |
|                                 gint x, gint y) {
 | |
|   AtkObject* atkObject = ATK_OBJECT(aComponent);
 | |
|   AccessibleWrap* accWrap = GetAccessibleWrap(atkObject);
 | |
|   if (accWrap) {
 | |
|     accWrap->ScrollToPoint(coords, x, y);
 | |
|     return TRUE;
 | |
|   }
 | |
| 
 | |
|   RemoteAccessible* proxy = GetProxy(atkObject);
 | |
|   if (proxy) {
 | |
|     proxy->ScrollToPoint(coords, x, y);
 | |
|     return TRUE;
 | |
|   }
 | |
| 
 | |
|   return FALSE;
 | |
| }
 | |
| }
 | |
| 
 | |
| AtkObject* refAccessibleAtPointHelper(AtkObject* aAtkObj, gint aX, gint aY,
 | |
|                                       AtkCoordType aCoordType) {
 | |
|   Accessible* acc = GetInternalObj(aAtkObj);
 | |
|   if (!acc) {
 | |
|     // This might be an ATK Socket.
 | |
|     acc = GetAccessibleWrap(aAtkObj);
 | |
|     if (!acc) {
 | |
|       return nullptr;
 | |
|     }
 | |
|   }
 | |
|   if (acc->IsLocal() && acc->AsLocal()->IsDefunct()) {
 | |
|     return nullptr;
 | |
|   }
 | |
| 
 | |
|   // Accessible::ChildAtPoint(x,y) is in screen pixels.
 | |
|   if (aCoordType == ATK_XY_WINDOW) {
 | |
|     mozilla::LayoutDeviceIntPoint winCoords =
 | |
|         nsAccUtils::GetScreenCoordsForWindow(acc);
 | |
|     aX += winCoords.x;
 | |
|     aY += winCoords.y;
 | |
|   }
 | |
| 
 | |
|   Accessible* accAtPoint =
 | |
|       acc->ChildAtPoint(aX, aY, Accessible::EWhichChildAtPoint::DeepestChild);
 | |
|   if (!accAtPoint) {
 | |
|     return nullptr;
 | |
|   }
 | |
|   roles::Role role = accAtPoint->Role();
 | |
|   if (role == roles::TEXT_LEAF || role == roles::STATICTEXT) {
 | |
|     // We don't include text leaf nodes in the ATK tree, so return the parent.
 | |
|     accAtPoint = accAtPoint->Parent();
 | |
|     MOZ_ASSERT(accAtPoint, "Text leaf should always have a parent");
 | |
|   }
 | |
|   AtkObject* atkObj = GetWrapperFor(accAtPoint);
 | |
|   if (atkObj) {
 | |
|     g_object_ref(atkObj);
 | |
|   }
 | |
|   return atkObj;
 | |
| }
 | |
| 
 | |
| void getExtentsHelper(AtkObject* aAtkObj, gint* aX, gint* aY, gint* aWidth,
 | |
|                       gint* aHeight, AtkCoordType aCoordType) {
 | |
|   AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj);
 | |
|   *aX = *aY = *aWidth = *aHeight = -1;
 | |
| 
 | |
|   if (accWrap) {
 | |
|     if (accWrap->IsDefunct()) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     mozilla::LayoutDeviceIntRect screenRect = accWrap->Bounds();
 | |
|     if (screenRect.IsEmpty()) return;
 | |
| 
 | |
|     if (aCoordType == ATK_XY_WINDOW) {
 | |
|       mozilla::LayoutDeviceIntPoint winCoords =
 | |
|           nsAccUtils::GetScreenCoordsForWindow(accWrap);
 | |
|       screenRect.x -= winCoords.x;
 | |
|       screenRect.y -= winCoords.y;
 | |
|     }
 | |
| 
 | |
|     *aX = screenRect.x;
 | |
|     *aY = screenRect.y;
 | |
|     *aWidth = screenRect.width;
 | |
|     *aHeight = screenRect.height;
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   if (RemoteAccessible* proxy = GetProxy(aAtkObj)) {
 | |
|     proxy->Extents(aCoordType == ATK_XY_WINDOW, aX, aY, aWidth, aHeight);
 | |
|   }
 | |
| }
 | |
| 
 | |
| void componentInterfaceInitCB(AtkComponentIface* aIface) {
 | |
|   NS_ASSERTION(aIface, "Invalid Interface");
 | |
|   if (MOZ_UNLIKELY(!aIface)) return;
 | |
| 
 | |
|   /*
 | |
|    * Use default implementation in atk for contains, get_position,
 | |
|    * and get_size
 | |
|    */
 | |
|   aIface->ref_accessible_at_point = refAccessibleAtPointCB;
 | |
|   aIface->get_extents = getExtentsCB;
 | |
|   aIface->grab_focus = grabFocusCB;
 | |
|   if (IsAtkVersionAtLeast(2, 30)) {
 | |
|     aIface->scroll_to = scrollToCB;
 | |
|     aIface->scroll_to_point = scrollToPointCB;
 | |
|   }
 | |
| }
 | 
