1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "InterfaceInitFuncs.h"
9 #include "LocalAccessible-inl.h"
10 #include "AccessibleWrap.h"
11 #include "nsAccUtils.h"
12 #include "nsCoreUtils.h"
14 #include "mozilla/Likely.h"
15 #include "mozilla/a11y/DocAccessibleParent.h"
16 #include "mozilla/a11y/RemoteAccessible.h"
17 #include "mozilla/dom/BrowserParent.h"
19 using namespace mozilla::a11y
;
23 static AtkObject
* refAccessibleAtPointCB(AtkComponent
* aComponent
, gint aAccX
,
24 gint aAccY
, AtkCoordType aCoordType
) {
25 return refAccessibleAtPointHelper(ATK_OBJECT(aComponent
), aAccX
, aAccY
,
29 static void getExtentsCB(AtkComponent
* aComponent
, gint
* aX
, gint
* aY
,
30 gint
* aWidth
, gint
* aHeight
, AtkCoordType aCoordType
) {
31 getExtentsHelper(ATK_OBJECT(aComponent
), aX
, aY
, aWidth
, aHeight
, aCoordType
);
34 static gboolean
grabFocusCB(AtkComponent
* aComponent
) {
35 AtkObject
* atkObject
= ATK_OBJECT(aComponent
);
36 AccessibleWrap
* accWrap
= GetAccessibleWrap(atkObject
);
42 RemoteAccessible
* proxy
= GetProxy(atkObject
);
51 // ScrollType is compatible
52 MOZ_CAN_RUN_SCRIPT_BOUNDARY
53 static gboolean
scrollToCB(AtkComponent
* aComponent
, AtkScrollType type
) {
54 AtkObject
* atkObject
= ATK_OBJECT(aComponent
);
55 if (RefPtr
<AccessibleWrap
> accWrap
= GetAccessibleWrap(atkObject
)) {
56 accWrap
->ScrollTo(type
);
60 RemoteAccessible
* proxy
= GetProxy(atkObject
);
62 proxy
->ScrollTo(type
);
69 // CoordType is compatible
70 static gboolean
scrollToPointCB(AtkComponent
* aComponent
, AtkCoordType coords
,
72 AtkObject
* atkObject
= ATK_OBJECT(aComponent
);
73 AccessibleWrap
* accWrap
= GetAccessibleWrap(atkObject
);
75 accWrap
->ScrollToPoint(coords
, x
, y
);
79 RemoteAccessible
* proxy
= GetProxy(atkObject
);
81 proxy
->ScrollToPoint(coords
, x
, y
);
89 AtkObject
* refAccessibleAtPointHelper(AtkObject
* aAtkObj
, gint aX
, gint aY
,
90 AtkCoordType aCoordType
) {
91 AccessibleOrProxy acc
= GetInternalObj(aAtkObj
);
93 // This might be an ATK Socket.
94 acc
= GetAccessibleWrap(aAtkObj
);
99 if (acc
.IsAccessible() && acc
.AsAccessible()->IsDefunct()) {
103 // AccessibleOrProxy::ChildAtPoint(x,y) is in screen pixels.
104 if (aCoordType
== ATK_XY_WINDOW
) {
105 nsINode
* node
= nullptr;
106 if (acc
.IsAccessible()) {
107 node
= acc
.AsAccessible()->GetNode();
109 // Use the XUL browser embedding this remote document.
110 auto browser
= static_cast<mozilla::dom::BrowserParent
*>(
111 acc
.AsProxy()->Document()->Manager());
112 node
= browser
->GetOwnerElement();
115 nsIntPoint winCoords
= nsCoreUtils::GetScreenCoordsForWindow(node
);
120 AccessibleOrProxy accAtPoint
=
121 acc
.ChildAtPoint(aX
, aY
, Accessible::EWhichChildAtPoint::DeepestChild
);
122 if (accAtPoint
.IsNull()) {
125 roles::Role role
= accAtPoint
.Role();
126 if (role
== roles::TEXT_LEAF
|| role
== roles::STATICTEXT
) {
127 // We don't include text leaf nodes in the ATK tree, so return the parent.
128 accAtPoint
= accAtPoint
.Parent();
129 MOZ_ASSERT(!accAtPoint
.IsNull(), "Text leaf should always have a parent");
131 AtkObject
* atkObj
= GetWrapperFor(accAtPoint
);
133 g_object_ref(atkObj
);
138 void getExtentsHelper(AtkObject
* aAtkObj
, gint
* aX
, gint
* aY
, gint
* aWidth
,
139 gint
* aHeight
, AtkCoordType aCoordType
) {
140 AccessibleWrap
* accWrap
= GetAccessibleWrap(aAtkObj
);
141 *aX
= *aY
= *aWidth
= *aHeight
= -1;
144 if (accWrap
->IsDefunct()) {
148 nsIntRect screenRect
= accWrap
->Bounds();
149 if (screenRect
.IsEmpty()) return;
151 if (aCoordType
== ATK_XY_WINDOW
) {
152 nsIntPoint winCoords
=
153 nsCoreUtils::GetScreenCoordsForWindow(accWrap
->GetNode());
154 screenRect
.x
-= winCoords
.x
;
155 screenRect
.y
-= winCoords
.y
;
160 *aWidth
= screenRect
.width
;
161 *aHeight
= screenRect
.height
;
165 if (RemoteAccessible
* proxy
= GetProxy(aAtkObj
)) {
166 proxy
->Extents(aCoordType
== ATK_XY_WINDOW
, aX
, aY
, aWidth
, aHeight
);
170 void componentInterfaceInitCB(AtkComponentIface
* aIface
) {
171 NS_ASSERTION(aIface
, "Invalid Interface");
172 if (MOZ_UNLIKELY(!aIface
)) return;
175 * Use default implementation in atk for contains, get_position,
178 aIface
->ref_accessible_at_point
= refAccessibleAtPointCB
;
179 aIface
->get_extents
= getExtentsCB
;
180 aIface
->grab_focus
= grabFocusCB
;
181 if (IsAtkVersionAtLeast(2, 30)) {
182 aIface
->scroll_to
= scrollToCB
;
183 aIface
->scroll_to_point
= scrollToPointCB
;