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"
14 #include "mozilla/Likely.h"
15 #include "mozilla/a11y/DocAccessibleParent.h"
16 #include "mozilla/a11y/RemoteAccessible.h"
17 #include "mozilla/dom/BrowserParent.h"
18 #include "mozilla/dom/Document.h"
19 #include "nsAccessibilityService.h"
21 using namespace mozilla
;
22 using namespace mozilla::a11y
;
26 static AtkObject
* refAccessibleAtPointCB(AtkComponent
* aComponent
, gint aAccX
,
27 gint aAccY
, AtkCoordType aCoordType
) {
28 return refAccessibleAtPointHelper(ATK_OBJECT(aComponent
), aAccX
, aAccY
,
32 static void getExtentsCB(AtkComponent
* aComponent
, gint
* aX
, gint
* aY
,
33 gint
* aWidth
, gint
* aHeight
, AtkCoordType aCoordType
) {
34 getExtentsHelper(ATK_OBJECT(aComponent
), aX
, aY
, aWidth
, aHeight
, aCoordType
);
37 static gboolean
grabFocusCB(AtkComponent
* aComponent
) {
38 AtkObject
* atkObject
= ATK_OBJECT(aComponent
);
39 Accessible
* acc
= GetInternalObj(atkObject
);
47 // ScrollType is compatible
48 MOZ_CAN_RUN_SCRIPT_BOUNDARY
49 static gboolean
scrollToCB(AtkComponent
* aComponent
, AtkScrollType type
) {
50 AtkObject
* atkObject
= ATK_OBJECT(aComponent
);
51 if (Accessible
* acc
= GetInternalObj(atkObject
)) {
59 // CoordType is compatible
60 static gboolean
scrollToPointCB(AtkComponent
* aComponent
, AtkCoordType coords
,
62 AtkObject
* atkObject
= ATK_OBJECT(aComponent
);
63 AccessibleWrap
* accWrap
= GetAccessibleWrap(atkObject
);
65 accWrap
->ScrollToPoint(coords
, x
, y
);
69 RemoteAccessible
* proxy
= GetProxy(atkObject
);
71 proxy
->ScrollToPoint(coords
, x
, y
);
79 AtkObject
* refAccessibleAtPointHelper(AtkObject
* aAtkObj
, gint aX
, gint aY
,
80 AtkCoordType aCoordType
) {
81 Accessible
* acc
= GetInternalObj(aAtkObj
);
86 // Accessible::ChildAtPoint(x,y) is in screen pixels.
87 if (aCoordType
== ATK_XY_WINDOW
) {
88 mozilla::LayoutDeviceIntPoint winCoords
=
89 nsAccUtils::GetScreenCoordsForWindow(acc
);
94 Accessible
* accAtPoint
=
95 acc
->ChildAtPoint(aX
, aY
, Accessible::EWhichChildAtPoint::DeepestChild
);
99 roles::Role role
= accAtPoint
->Role();
100 if (role
== roles::TEXT_LEAF
|| role
== roles::STATICTEXT
) {
101 // We don't include text leaf nodes in the ATK tree, so return the parent.
102 accAtPoint
= accAtPoint
->Parent();
103 MOZ_ASSERT(accAtPoint
, "Text leaf should always have a parent");
105 AtkObject
* atkObj
= GetWrapperFor(accAtPoint
);
107 g_object_ref(atkObj
);
112 static double getScaleFactor(Accessible
* aAccessible
) {
113 DocAccessible
* docAcc
= nullptr;
114 if (LocalAccessible
* localAcc
= aAccessible
->AsLocal()) {
115 docAcc
= localAcc
->Document();
117 RemoteAccessible
* remote
= aAccessible
->AsRemote();
118 LocalAccessible
* outerDoc
= remote
->OuterDocOfRemoteBrowser();
120 docAcc
= outerDoc
->Document();
124 if (!docAcc
|| !docAcc
->DocumentNode()) {
128 nsCOMPtr
<nsIWidget
> rootWidget
=
129 nsContentUtils::WidgetForDocument(docAcc
->DocumentNode());
134 if (RefPtr
<nsWindow
> window
=
135 static_cast<nsWindow
*>(rootWidget
->GetTopLevelWidget())) {
136 return window
->FractionalScaleFactor();
142 void getExtentsHelper(AtkObject
* aAtkObj
, gint
* aX
, gint
* aY
, gint
* aWidth
,
143 gint
* aHeight
, AtkCoordType aCoordType
) {
144 *aX
= *aY
= *aWidth
= *aHeight
= -1;
146 Accessible
* acc
= GetInternalObj(aAtkObj
);
151 mozilla::LayoutDeviceIntRect screenRect
= acc
->Bounds();
152 if (screenRect
.IsEmpty()) {
156 if (aCoordType
== ATK_XY_WINDOW
) {
157 mozilla::LayoutDeviceIntPoint winCoords
=
158 nsAccUtils::GetScreenCoordsForWindow(acc
);
159 screenRect
.x
-= winCoords
.x
;
160 screenRect
.y
-= winCoords
.y
;
163 double scaleFactor
= getScaleFactor(acc
);
165 *aX
= screenRect
.x
/ scaleFactor
;
166 *aY
= screenRect
.y
/ scaleFactor
;
167 *aWidth
= screenRect
.width
/ scaleFactor
;
168 *aHeight
= screenRect
.height
/ scaleFactor
;
171 void componentInterfaceInitCB(AtkComponentIface
* aIface
) {
172 NS_ASSERTION(aIface
, "Invalid Interface");
173 if (MOZ_UNLIKELY(!aIface
)) return;
176 * Use default implementation in atk for contains, get_position,
179 aIface
->ref_accessible_at_point
= refAccessibleAtPointCB
;
180 aIface
->get_extents
= getExtentsCB
;
181 aIface
->grab_focus
= grabFocusCB
;
182 if (IsAtkVersionAtLeast(2, 30)) {
183 aIface
->scroll_to
= scrollToCB
;
184 aIface
->scroll_to_point
= scrollToPointCB
;