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 Accessible
* acc
= GetInternalObj(atkObject
);
44 // ScrollType is compatible
45 MOZ_CAN_RUN_SCRIPT_BOUNDARY
46 static gboolean
scrollToCB(AtkComponent
* aComponent
, AtkScrollType type
) {
47 AtkObject
* atkObject
= ATK_OBJECT(aComponent
);
48 if (RefPtr
<AccessibleWrap
> accWrap
= GetAccessibleWrap(atkObject
)) {
49 accWrap
->ScrollTo(type
);
53 RemoteAccessible
* proxy
= GetProxy(atkObject
);
55 proxy
->ScrollTo(type
);
62 // CoordType is compatible
63 static gboolean
scrollToPointCB(AtkComponent
* aComponent
, AtkCoordType coords
,
65 AtkObject
* atkObject
= ATK_OBJECT(aComponent
);
66 AccessibleWrap
* accWrap
= GetAccessibleWrap(atkObject
);
68 accWrap
->ScrollToPoint(coords
, x
, y
);
72 RemoteAccessible
* proxy
= GetProxy(atkObject
);
74 proxy
->ScrollToPoint(coords
, x
, y
);
82 AtkObject
* refAccessibleAtPointHelper(AtkObject
* aAtkObj
, gint aX
, gint aY
,
83 AtkCoordType aCoordType
) {
84 Accessible
* acc
= GetInternalObj(aAtkObj
);
86 // This might be an ATK Socket.
87 acc
= GetAccessibleWrap(aAtkObj
);
92 if (acc
->IsLocal() && acc
->AsLocal()->IsDefunct()) {
96 // Accessible::ChildAtPoint(x,y) is in screen pixels.
97 if (aCoordType
== ATK_XY_WINDOW
) {
98 nsINode
* node
= nullptr;
100 node
= acc
->AsLocal()->GetNode();
102 // Use the XUL browser embedding this remote document.
103 auto browser
= static_cast<mozilla::dom::BrowserParent
*>(
104 acc
->AsRemote()->Document()->Manager());
105 node
= browser
->GetOwnerElement();
108 mozilla::LayoutDeviceIntPoint winCoords
=
109 nsCoreUtils::GetScreenCoordsForWindow(node
);
114 Accessible
* accAtPoint
=
115 acc
->ChildAtPoint(aX
, aY
, Accessible::EWhichChildAtPoint::DeepestChild
);
119 roles::Role role
= accAtPoint
->Role();
120 if (role
== roles::TEXT_LEAF
|| role
== roles::STATICTEXT
) {
121 // We don't include text leaf nodes in the ATK tree, so return the parent.
122 accAtPoint
= accAtPoint
->Parent();
123 MOZ_ASSERT(accAtPoint
, "Text leaf should always have a parent");
125 AtkObject
* atkObj
= GetWrapperFor(accAtPoint
);
127 g_object_ref(atkObj
);
132 void getExtentsHelper(AtkObject
* aAtkObj
, gint
* aX
, gint
* aY
, gint
* aWidth
,
133 gint
* aHeight
, AtkCoordType aCoordType
) {
134 AccessibleWrap
* accWrap
= GetAccessibleWrap(aAtkObj
);
135 *aX
= *aY
= *aWidth
= *aHeight
= -1;
138 if (accWrap
->IsDefunct()) {
142 mozilla::LayoutDeviceIntRect screenRect
= accWrap
->Bounds();
143 if (screenRect
.IsEmpty()) return;
145 if (aCoordType
== ATK_XY_WINDOW
) {
146 mozilla::LayoutDeviceIntPoint winCoords
=
147 nsCoreUtils::GetScreenCoordsForWindow(accWrap
->GetNode());
148 screenRect
.x
-= winCoords
.x
;
149 screenRect
.y
-= winCoords
.y
;
154 *aWidth
= screenRect
.width
;
155 *aHeight
= screenRect
.height
;
159 if (RemoteAccessible
* proxy
= GetProxy(aAtkObj
)) {
160 proxy
->Extents(aCoordType
== ATK_XY_WINDOW
, aX
, aY
, aWidth
, aHeight
);
164 void componentInterfaceInitCB(AtkComponentIface
* aIface
) {
165 NS_ASSERTION(aIface
, "Invalid Interface");
166 if (MOZ_UNLIKELY(!aIface
)) return;
169 * Use default implementation in atk for contains, get_position,
172 aIface
->ref_accessible_at_point
= refAccessibleAtPointCB
;
173 aIface
->get_extents
= getExtentsCB
;
174 aIface
->grab_focus
= grabFocusCB
;
175 if (IsAtkVersionAtLeast(2, 30)) {
176 aIface
->scroll_to
= scrollToCB
;
177 aIface
->scroll_to_point
= scrollToPointCB
;