summaryrefslogtreecommitdiffstats
path: root/accessible/ipc/win/handler/AccessibleHandler.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--accessible/ipc/win/handler/AccessibleHandler.h336
1 files changed, 336 insertions, 0 deletions
diff --git a/accessible/ipc/win/handler/AccessibleHandler.h b/accessible/ipc/win/handler/AccessibleHandler.h
new file mode 100644
index 0000000000..f99091d6c3
--- /dev/null
+++ b/accessible/ipc/win/handler/AccessibleHandler.h
@@ -0,0 +1,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