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/. */
6
7 #include "InterfaceInitFuncs.h"
8
9 #include "AccessibleWrap.h"
10 #include "nsAccUtils.h"
11 #include "nsCoreUtils.h"
12 #include "nsMai.h"
13 #include "mozilla/Likely.h"
14 #include "mozilla/a11y/ProxyAccessible.h"
15
16 using namespace mozilla::a11y;
17
18 extern "C" {
19
20 static AtkObject*
refAccessibleAtPointCB(AtkComponent * aComponent,gint aAccX,gint aAccY,AtkCoordType aCoordType)21 refAccessibleAtPointCB(AtkComponent* aComponent, gint aAccX, gint aAccY,
22 AtkCoordType aCoordType)
23 {
24 return refAccessibleAtPointHelper(ATK_OBJECT(aComponent),
25 aAccX, aAccY, aCoordType);
26 }
27
28 static void
getExtentsCB(AtkComponent * aComponent,gint * aX,gint * aY,gint * aWidth,gint * aHeight,AtkCoordType aCoordType)29 getExtentsCB(AtkComponent* aComponent, gint* aX, gint* aY,
30 gint* aWidth, gint* aHeight, AtkCoordType aCoordType)
31 {
32 getExtentsHelper(ATK_OBJECT(aComponent),
33 aX, aY, aWidth, aHeight, aCoordType);
34 }
35
36 static gboolean
grabFocusCB(AtkComponent * aComponent)37 grabFocusCB(AtkComponent* aComponent)
38 {
39 AtkObject* atkObject = ATK_OBJECT(aComponent);
40 AccessibleWrap* accWrap = GetAccessibleWrap(atkObject);
41 if (accWrap) {
42 accWrap->TakeFocus();
43 return TRUE;
44 }
45
46 ProxyAccessible* proxy = GetProxy(atkObject);
47 if (proxy) {
48 proxy->TakeFocus();
49 return TRUE;
50 }
51
52 return FALSE;
53 }
54 }
55
56 AtkObject*
refAccessibleAtPointHelper(AtkObject * aAtkObj,gint aX,gint aY,AtkCoordType aCoordType)57 refAccessibleAtPointHelper(AtkObject* aAtkObj, gint aX, gint aY,
58 AtkCoordType aCoordType)
59 {
60 AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj);
61 if (accWrap) {
62 if (accWrap->IsDefunct() || nsAccUtils::MustPrune(accWrap)) {
63 return nullptr;
64 }
65
66 // Accessible::ChildAtPoint(x,y) is in screen pixels.
67 if (aCoordType == ATK_XY_WINDOW) {
68 nsIntPoint winCoords =
69 nsCoreUtils::GetScreenCoordsForWindow(accWrap->GetNode());
70 aX += winCoords.x;
71 aY += winCoords.y;
72 }
73
74 Accessible* accAtPoint = accWrap->ChildAtPoint(aX, aY,
75 Accessible::eDirectChild);
76 if (!accAtPoint) {
77 return nullptr;
78 }
79
80 AtkObject* atkObj = AccessibleWrap::GetAtkObject(accAtPoint);
81 if (atkObj) {
82 g_object_ref(atkObj);
83 }
84
85 return atkObj;
86 }
87
88 if (ProxyAccessible* proxy = GetProxy(aAtkObj)) {
89 ProxyAccessible* result =
90 proxy->AccessibleAtPoint(aX, aY, aCoordType == ATK_XY_WINDOW);
91 AtkObject* atkObj = result ? GetWrapperFor(result) : nullptr;
92 if (atkObj) {
93 g_object_ref(atkObj);
94 }
95 return atkObj;
96 }
97
98 return nullptr;
99 }
100
101 void
getExtentsHelper(AtkObject * aAtkObj,gint * aX,gint * aY,gint * aWidth,gint * aHeight,AtkCoordType aCoordType)102 getExtentsHelper(AtkObject* aAtkObj,
103 gint* aX, gint* aY, gint* aWidth, gint* aHeight,
104 AtkCoordType aCoordType)
105 {
106 AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj);
107 *aX = *aY = *aWidth = *aHeight = 0;
108
109 if (accWrap) {
110 if (accWrap->IsDefunct()) {
111 return;
112 }
113
114 nsIntRect screenRect = accWrap->Bounds();
115 if (screenRect.IsEmpty())
116 return;
117
118 if (aCoordType == ATK_XY_WINDOW) {
119 nsIntPoint winCoords =
120 nsCoreUtils::GetScreenCoordsForWindow(accWrap->GetNode());
121 screenRect.x -= winCoords.x;
122 screenRect.y -= winCoords.y;
123 }
124
125 *aX = screenRect.x;
126 *aY = screenRect.y;
127 *aWidth = screenRect.width;
128 *aHeight = screenRect.height;
129 return;
130 }
131
132 if (ProxyAccessible* proxy = GetProxy(aAtkObj)) {
133 proxy->Extents(aCoordType == ATK_XY_WINDOW, aX, aY, aWidth, aHeight);
134 }
135 }
136
137 void
componentInterfaceInitCB(AtkComponentIface * aIface)138 componentInterfaceInitCB(AtkComponentIface* aIface)
139 {
140 NS_ASSERTION(aIface, "Invalid Interface");
141 if(MOZ_UNLIKELY(!aIface))
142 return;
143
144 /*
145 * Use default implementation in atk for contains, get_position,
146 * and get_size
147 */
148 aIface->ref_accessible_at_point = refAccessibleAtPointCB;
149 aIface->get_extents = getExtentsCB;
150 aIface->grab_focus = grabFocusCB;
151 }
152