1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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/. */
#ifndef mozilla_a11y_AccessibleHandler_h
#define mozilla_a11y_AccessibleHandler_h
#define NEWEST_IA2_BASENAME Accessible2_3
#define __GENIFACE(base) I##base
#define INTERFACEFOR(base) __GENIFACE(base)
#define NEWEST_IA2_INTERFACE INTERFACEFOR(NEWEST_IA2_BASENAME)
#define __GENIID(iface) IID_##iface
#define IIDFOR(iface) __GENIID(iface)
#define NEWEST_IA2_IID IIDFOR(NEWEST_IA2_INTERFACE)
#if defined(__midl) || defined(__WIDL__)
import "Accessible2_3.idl";
#else
# include "HandlerData.h"
# include <windows.h>
namespace mozilla {
namespace a11y {
static const GUID kUnsupportedServices[] = {
// clang-format off
// Unknown, queried by Windows on devices with touch screens or similar devices
// connected.
{0x33f139ee, 0xe509, 0x47f7, {0xbf, 0x39, 0x83, 0x76, 0x44, 0xf7, 0x45, 0x76}},
// Unknown, queried by Windows
{0xFDA075CF, 0x7C8B, 0x498C, { 0xB5, 0x14, 0xA9, 0xCB, 0x52, 0x1B, 0xBF, 0xB4 }},
// Unknown, queried by Windows
{0x8EDAA462, 0x21F4, 0x4C87, { 0xA0, 0x12, 0xB3, 0xCD, 0xA3, 0xAB, 0x01, 0xFC }},
// Unknown, queried by Windows
{0xacd46652, 0x829d, 0x41cb, { 0xa5, 0xfc, 0x17, 0xac, 0xf4, 0x36, 0x61, 0xac }},
// SID_IsUIAutomationObject (undocumented), queried by Windows
{0xb96fdb85, 0x7204, 0x4724, { 0x84, 0x2b, 0xc7, 0x05, 0x9d, 0xed, 0xb9, 0xd0 }},
// IIS_IsOleaccProxy (undocumented), queried by Windows
{0x902697FA, 0x80E4, 0x4560, {0x80, 0x2A, 0xA1, 0x3F, 0x22, 0xA6, 0x47, 0x09}},
// IID_IHTMLElement, queried by JAWS
{0x3050F1FF, 0x98B5, 0x11CF, {0xBB, 0x82, 0x00, 0xAA, 0x00, 0xBD, 0xCE, 0x0B}}
// clang-format on
};
}
} // namespace mozilla
# if !defined(MOZILLA_INTERNAL_API)
# include "Accessible2_3.h"
# include "AccessibleHyperlink.h"
# include "AccessibleHypertext2.h"
# include "AccessibleTableCell.h"
# include "Handler.h"
# include "mozilla/mscom/StructStream.h"
# include "mozilla/UniquePtr.h"
# include <ocidl.h>
# include <servprov.h>
namespace mozilla {
namespace a11y {
class AccessibleHandler final : public mscom::Handler,
public NEWEST_IA2_INTERFACE,
public IServiceProvider,
public IProvideClassInfo,
public IAccessibleHyperlink,
public IAccessibleTableCell,
public IAccessibleHypertext2 {
public:
static HRESULT Create(IUnknown* aOuter, REFIID aIid, void** aOutInterface);
// mscom::Handler
HRESULT QueryHandlerInterface(IUnknown* aProxyUnknown, REFIID aIid,
void** aOutInterface) override;
HRESULT ReadHandlerPayload(IStream* aStream, REFIID aIid) override;
REFIID MarshalAs(REFIID aRequestedIid) override;
HRESULT GetMarshalInterface(REFIID aMarshalAsIid, NotNull<IUnknown*> aProxy,
NotNull<IID*> aOutIid,
NotNull<IUnknown**> aOutUnk) override;
HRESULT GetHandlerPayloadSize(REFIID aIid, DWORD* aOutPayloadSize) override;
HRESULT WriteHandlerPayload(IStream* aStream, REFIID aIId) override;
// IUnknown
STDMETHODIMP QueryInterface(REFIID riid, void** ppv) override;
STDMETHODIMP_(ULONG) AddRef() override;
STDMETHODIMP_(ULONG) Release() override;
// IDispatch
STDMETHODIMP GetTypeInfoCount(UINT* pctinfo) override;
STDMETHODIMP GetTypeInfo(UINT iTInfo, LCID lcid,
ITypeInfo** ppTInfo) override;
STDMETHODIMP GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames,
LCID lcid, DISPID* rgDispId) override;
STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
DISPPARAMS* pDispParams, VARIANT* pVarResult,
EXCEPINFO* pExcepInfo, UINT* puArgErr) override;
// IAccessible
STDMETHODIMP get_accParent(IDispatch** ppdispParent) override;
STDMETHODIMP get_accChildCount(long* pcountChildren) override;
STDMETHODIMP get_accChild(VARIANT varChild, IDispatch** ppdispChild) override;
STDMETHODIMP get_accName(VARIANT varChild, BSTR* pszName) override;
STDMETHODIMP get_accValue(VARIANT varChild, BSTR* pszValue) override;
STDMETHODIMP get_accDescription(VARIANT varChild,
BSTR* pszDescription) override;
STDMETHODIMP get_accRole(VARIANT varChild, VARIANT* pvarRole) override;
STDMETHODIMP get_accState(VARIANT varChild, VARIANT* pvarState) override;
STDMETHODIMP get_accHelp(VARIANT varChild, BSTR* pszHelp) override;
STDMETHODIMP get_accHelpTopic(BSTR* pszHelpFile, VARIANT varChild,
long* pidTopic) override;
STDMETHODIMP get_accKeyboardShortcut(VARIANT varChild,
BSTR* pszKeyboardShortcut) override;
STDMETHODIMP get_accFocus(VARIANT* pvarChild) override;
STDMETHODIMP get_accSelection(VARIANT* pvarChildren) override;
STDMETHODIMP get_accDefaultAction(VARIANT varChild,
BSTR* pszDefaultAction) override;
STDMETHODIMP accSelect(long flagsSelect, VARIANT varChild) override;
STDMETHODIMP accLocation(long* pxLeft, long* pyTop, long* pcxWidth,
long* pcyHeight, VARIANT varChild) override;
STDMETHODIMP accNavigate(long navDir, VARIANT varStart,
VARIANT* pvarEndUpAt) override;
STDMETHODIMP accHitTest(long xLeft, long yTop, VARIANT* pvarChild) override;
STDMETHODIMP accDoDefaultAction(VARIANT varChild) override;
STDMETHODIMP put_accName(VARIANT varChild, BSTR szName) override;
STDMETHODIMP put_accValue(VARIANT varChild, BSTR szValue) override;
// IAccessible2
STDMETHODIMP get_nRelations(long* nRelations) override;
STDMETHODIMP get_relation(long relationIndex,
IAccessibleRelation** relation) override;
STDMETHODIMP get_relations(long maxRelations, IAccessibleRelation** relations,
long* nRelations) override;
STDMETHODIMP role(long* role) override;
STDMETHODIMP scrollTo(IA2ScrollType scrollType) override;
STDMETHODIMP scrollToPoint(IA2CoordinateType coordinateType, long x,
long y) override;
STDMETHODIMP get_groupPosition(long* groupLevel, long* similarItemsInGroup,
long* positionInGroup) override;
STDMETHODIMP get_states(AccessibleStates* states) override;
STDMETHODIMP get_extendedRole(BSTR* extendedRole) override;
STDMETHODIMP get_localizedExtendedRole(BSTR* localizedExtendedRole) override;
STDMETHODIMP get_nExtendedStates(long* nExtendedStates) override;
STDMETHODIMP get_extendedStates(long maxExtendedStates, BSTR** extendedStates,
long* nExtendedStates) override;
STDMETHODIMP get_localizedExtendedStates(
long maxLocalizedExtendedStates, BSTR** localizedExtendedStates,
long* nLocalizedExtendedStates) override;
STDMETHODIMP get_uniqueID(long* uniqueID) override;
STDMETHODIMP get_windowHandle(HWND* windowHandle) override;
STDMETHODIMP get_indexInParent(long* indexInParent) override;
STDMETHODIMP get_locale(IA2Locale* locale) override;
STDMETHODIMP get_attributes(BSTR* attributes) override;
// IAccessible2_2
STDMETHODIMP get_attribute(BSTR name, VARIANT* attribute) override;
STDMETHODIMP get_accessibleWithCaret(IUnknown** accessible,
long* caretOffset) override;
STDMETHODIMP get_relationTargetsOfType(BSTR type, long maxTargets,
IUnknown*** targets,
long* nTargets) override;
// IAccessible2_3
STDMETHODIMP get_selectionRanges(IA2Range** ranges, long* nRanges) override;
// IServiceProvider
STDMETHODIMP QueryService(REFGUID aServiceId, REFIID aIid,
void** aOutInterface) override;
// IProvideClassInfo
STDMETHODIMP GetClassInfo(ITypeInfo** aOutTypeInfo) override;
// IAccessibleAction
STDMETHODIMP nActions(long* nActions) override;
STDMETHODIMP doAction(long actionIndex) override;
STDMETHODIMP get_description(long actionIndex, BSTR* description) override;
STDMETHODIMP get_keyBinding(long actionIndex, long nMaxBindings,
BSTR** keyBindings, long* nBindings) override;
STDMETHODIMP get_name(long actionIndex, BSTR* name) override;
STDMETHODIMP get_localizedName(long actionIndex,
BSTR* localizedName) override;
// IAccessibleHyperlink
STDMETHODIMP get_anchor(long index, VARIANT* anchor) override;
STDMETHODIMP get_anchorTarget(long index, VARIANT* anchorTarget) override;
STDMETHODIMP get_startIndex(long* index) override;
STDMETHODIMP get_endIndex(long* index) override;
STDMETHODIMP get_valid(boolean* valid) override;
// IAccessibleTableCell
STDMETHODIMP get_columnExtent(long* nColumnsSpanned) override;
STDMETHODIMP get_columnHeaderCells(IUnknown*** cellAccessibles,
long* nColumnHeaderCells) override;
STDMETHODIMP get_columnIndex(long* columnIndex) override;
STDMETHODIMP get_rowExtent(long* nRowsSpanned) override;
STDMETHODIMP get_rowHeaderCells(IUnknown*** cellAccessibles,
long* nRowHeaderCells) override;
STDMETHODIMP get_rowIndex(long* rowIndex) override;
STDMETHODIMP get_isSelected(boolean* isSelected) override;
STDMETHODIMP get_rowColumnExtents(long* row, long* column, long* rowExtents,
long* columnExtents,
boolean* isSelected) override;
STDMETHODIMP get_table(IUnknown** table) override;
// IAccessibleText
STDMETHODIMP addSelection(long startOffset, long endOffset) override;
STDMETHODIMP get_attributes(long offset, long* startOffset, long* endOffset,
BSTR* textAttributes) override;
STDMETHODIMP get_caretOffset(long* offset) override;
STDMETHODIMP get_characterExtents(long offset,
enum IA2CoordinateType coordType, long* x,
long* y, long* width,
long* height) override;
STDMETHODIMP get_nSelections(long* nSelections) override;
STDMETHODIMP get_offsetAtPoint(long x, long y,
enum IA2CoordinateType coordType,
long* offset) override;
STDMETHODIMP get_selection(long selectionIndex, long* startOffset,
long* endOffset) override;
STDMETHODIMP get_text(long startOffset, long endOffset, BSTR* text) override;
STDMETHODIMP get_textBeforeOffset(long offset,
enum IA2TextBoundaryType boundaryType,
long* startOffset, long* endOffset,
BSTR* text) override;
STDMETHODIMP get_textAfterOffset(long offset,
enum IA2TextBoundaryType boundaryType,
long* startOffset, long* endOffset,
BSTR* text) override;
STDMETHODIMP get_textAtOffset(long offset,
enum IA2TextBoundaryType boundaryType,
long* startOffset, long* endOffset,
BSTR* text) override;
STDMETHODIMP removeSelection(long selectionIndex) override;
STDMETHODIMP setCaretOffset(long offset) override;
STDMETHODIMP setSelection(long selectionIndex, long startOffset,
long endOffset) override;
STDMETHODIMP get_nCharacters(long* nCharacters) override;
STDMETHODIMP scrollSubstringTo(long startIndex, long endIndex,
enum IA2ScrollType scrollType) override;
STDMETHODIMP scrollSubstringToPoint(long startIndex, long endIndex,
enum IA2CoordinateType coordinateType,
long x, long y) override;
STDMETHODIMP get_newText(IA2TextSegment* newText) override;
STDMETHODIMP get_oldText(IA2TextSegment* oldText) override;
// IAccessibleHypertext
STDMETHODIMP get_nHyperlinks(long* hyperlinkCount) override;
STDMETHODIMP get_hyperlink(long index,
IAccessibleHyperlink** hyperlink) override;
STDMETHODIMP get_hyperlinkIndex(long charIndex,
long* hyperlinkIndex) override;
// IAccessibleHypertext2
STDMETHODIMP get_hyperlinks(IAccessibleHyperlink*** hyperlinks,
long* nHyperlinks) override;
private:
AccessibleHandler(IUnknown* aOuter, HRESULT* aResult);
virtual ~AccessibleHandler();
HRESULT ResolveIA2();
HRESULT ResolveIDispatch();
HRESULT ResolveIAHyperlink();
HRESULT ResolveIAHypertext();
HRESULT ResolveIATableCell();
HRESULT MaybeUpdateCachedData();
HRESULT GetAllTextInfo(BSTR* aText);
void ClearTextCache();
HRESULT GetRelationsInfo();
void ClearRelationCache();
RefPtr<IUnknown> mDispatchUnk;
/**
* Handlers aggregate their proxies. This means that their proxies delegate
* their IUnknown implementation to us.
*
* mDispatchUnk and the result of Handler::GetProxy() are both strong
* references to the aggregated objects. OTOH, any interfaces that are QI'd
* from those aggregated objects have delegated unknowns.
*
* AddRef'ing an interface with a delegated unknown ends up incrementing the
* refcount of the *aggregator*. Since we are the aggregator of mDispatchUnk
* and of the wrapped proxy, holding a strong reference to any interfaces
* QI'd off of those objects would create a reference cycle.
*
* We may hold onto pointers to those references, but when we query them we
* must immediately Release() them to prevent these cycles.
*
* It is safe for us to use these raw pointers because the aggregated
* objects's lifetimes are proper subsets of our own lifetime.
*/
IDispatch* mDispatch; // weak
NEWEST_IA2_INTERFACE* mIA2PassThru; // weak
IServiceProvider* mServProvPassThru; // weak
IAccessibleHyperlink* mIAHyperlinkPassThru; // weak
IAccessibleTableCell* mIATableCellPassThru; // weak
IAccessibleHypertext2* mIAHypertextPassThru; // weak
IA2Payload mCachedData;
bool mCachedDynamicDataMarshaledByCom;
UniquePtr<mscom::StructToStream> mSerializer;
uint32_t mCacheGen;
IAccessibleHyperlink** mCachedHyperlinks;
long mCachedNHyperlinks;
IA2TextSegment* mCachedTextAttribRuns;
long mCachedNTextAttribRuns;
IARelationData* mCachedRelations;
long mCachedNRelations;
bool mIsEmulatedWindow;
};
inline static BSTR CopyBSTR(BSTR aSrc) {
if (!aSrc) {
return nullptr;
}
return ::SysAllocStringLen(aSrc, ::SysStringLen(aSrc));
}
} // namespace a11y
} // namespace mozilla
# endif // !defined(MOZILLA_INTERNAL_API)
#endif // defined(__midl)
#endif // mozilla_a11y_AccessibleHandler_h
|