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