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 #ifndef mozilla_a11y_AccessibleWrap_h_
8 #define mozilla_a11y_AccessibleWrap_h_
9 
10 #include "nsCOMPtr.h"
11 #include "Accessible.h"
12 #include "Accessible2.h"
13 #include "ia2Accessible.h"
14 #include "ia2AccessibleComponent.h"
15 #include "ia2AccessibleHyperlink.h"
16 #include "ia2AccessibleValue.h"
17 #include "mozilla/a11y/AccessibleHandler.h"
18 #include "mozilla/a11y/MsaaIdGenerator.h"
19 #include "mozilla/a11y/ProxyAccessible.h"
20 #include "mozilla/Attributes.h"
21 #include "mozilla/mscom/Utils.h"
22 
23 #ifdef __GNUC__
24 // Inheriting from both XPCOM and MSCOM interfaces causes a lot of warnings
25 // about virtual functions being hidden by each other. This is done by
26 // design, so silence the warning.
27 #pragma GCC diagnostic ignored "-Woverloaded-virtual"
28 #endif
29 
30 namespace mozilla {
31 namespace a11y {
32 class DocProxyAccessibleWrap;
33 
34 class AccessibleWrap : public Accessible,
35                        public ia2Accessible,
36                        public ia2AccessibleComponent,
37                        public ia2AccessibleHyperlink,
38                        public ia2AccessibleValue {
39  public:  // construction, destruction
40   AccessibleWrap(nsIContent *aContent, DocAccessible *aDoc);
41 
42   // nsISupports
43   NS_DECL_ISUPPORTS_INHERITED
44 
45  public:  // IUnknown methods - see iunknown.h for documentation
46   STDMETHODIMP QueryInterface(REFIID, void **) override;
47 
48   // Return the registered OLE class ID of this object's CfDataObj.
49   CLSID GetClassID() const;
50 
51  public:  // COM interface IAccessible
52   virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accParent(
53       /* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *ppdispParent)
54       override;
55 
56   virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accChildCount(
57       /* [retval][out] */ long __RPC_FAR *pcountChildren) override;
58 
59   virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accChild(
60       /* [in] */ VARIANT varChild,
61       /* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *ppdispChild) override;
62 
63   virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accName(
64       /* [optional][in] */ VARIANT varChild,
65       /* [retval][out] */ BSTR __RPC_FAR *pszName) override;
66 
67   virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accValue(
68       /* [optional][in] */ VARIANT varChild,
69       /* [retval][out] */ BSTR __RPC_FAR *pszValue) override;
70 
71   virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accDescription(
72       /* [optional][in] */ VARIANT varChild,
73       /* [retval][out] */ BSTR __RPC_FAR *pszDescription) override;
74 
75   virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accRole(
76       /* [optional][in] */ VARIANT varChild,
77       /* [retval][out] */ VARIANT __RPC_FAR *pvarRole) override;
78 
79   virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accState(
80       /* [optional][in] */ VARIANT varChild,
81       /* [retval][out] */ VARIANT __RPC_FAR *pvarState) override;
82 
83   virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accHelp(
84       /* [optional][in] */ VARIANT varChild,
85       /* [retval][out] */ BSTR __RPC_FAR *pszHelp) override;
86 
87   virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accHelpTopic(
88       /* [out] */ BSTR __RPC_FAR *pszHelpFile,
89       /* [optional][in] */ VARIANT varChild,
90       /* [retval][out] */ long __RPC_FAR *pidTopic) override;
91 
92   virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accKeyboardShortcut(
93       /* [optional][in] */ VARIANT varChild,
94       /* [retval][out] */ BSTR __RPC_FAR *pszKeyboardShortcut) override;
95 
96   virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accFocus(
97       /* [retval][out] */ VARIANT __RPC_FAR *pvarChild) override;
98 
99   virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accSelection(
100       /* [retval][out] */ VARIANT __RPC_FAR *pvarChildren) override;
101 
102   virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accDefaultAction(
103       /* [optional][in] */ VARIANT varChild,
104       /* [retval][out] */ BSTR __RPC_FAR *pszDefaultAction) override;
105 
106   virtual /* [id] */ HRESULT STDMETHODCALLTYPE accSelect(
107       /* [in] */ long flagsSelect,
108       /* [optional][in] */ VARIANT varChild) override;
109 
110   virtual /* [id] */ HRESULT STDMETHODCALLTYPE accLocation(
111       /* [out] */ long __RPC_FAR *pxLeft,
112       /* [out] */ long __RPC_FAR *pyTop,
113       /* [out] */ long __RPC_FAR *pcxWidth,
114       /* [out] */ long __RPC_FAR *pcyHeight,
115       /* [optional][in] */ VARIANT varChild) override;
116 
117   virtual /* [id] */ HRESULT STDMETHODCALLTYPE accNavigate(
118       /* [in] */ long navDir,
119       /* [optional][in] */ VARIANT varStart,
120       /* [retval][out] */ VARIANT __RPC_FAR *pvarEndUpAt) override;
121 
122   virtual /* [id] */ HRESULT STDMETHODCALLTYPE accHitTest(
123       /* [in] */ long xLeft,
124       /* [in] */ long yTop,
125       /* [retval][out] */ VARIANT __RPC_FAR *pvarChild) override;
126 
127   virtual /* [id] */ HRESULT STDMETHODCALLTYPE accDoDefaultAction(
128       /* [optional][in] */ VARIANT varChild) override;
129 
130   virtual /* [id][propput] */ HRESULT STDMETHODCALLTYPE put_accName(
131       /* [optional][in] */ VARIANT varChild,
132       /* [in] */ BSTR szName) override;
133 
134   virtual /* [id][propput] */ HRESULT STDMETHODCALLTYPE put_accValue(
135       /* [optional][in] */ VARIANT varChild,
136       /* [in] */ BSTR szValue) override;
137 
138   // IDispatch (support of scripting languages like VB)
139   virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT *pctinfo) override;
140 
141   virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT iTInfo, LCID lcid,
142                                                 ITypeInfo **ppTInfo) override;
143 
144   virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID riid,
145                                                   LPOLESTR *rgszNames,
146                                                   UINT cNames, LCID lcid,
147                                                   DISPID *rgDispId) override;
148 
149   virtual HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid,
150                                            LCID lcid, WORD wFlags,
151                                            DISPPARAMS *pDispParams,
152                                            VARIANT *pVarResult,
153                                            EXCEPINFO *pExcepInfo,
154                                            UINT *puArgErr) override;
155 
156   // Accessible
157   virtual nsresult HandleAccEvent(AccEvent *aEvent) override;
158   virtual void Shutdown() override;
159 
160   // Helper methods
161   static int32_t GetChildIDFor(Accessible *aAccessible);
162   static HWND GetHWNDFor(Accessible *aAccessible);
163 
164   static void FireWinEvent(Accessible *aTarget, uint32_t aEventType);
165 
166   /**
167    * System caret support: update the Windows caret position.
168    * The system caret works more universally than the MSAA caret
169    * For example, Window-Eyes, JAWS, ZoomText and Windows Tablet Edition use it
170    * We will use an invisible system caret.
171    * Gecko is still responsible for drawing its own caret
172    */
173   void UpdateSystemCaretFor(Accessible *aAccessible);
174   static void UpdateSystemCaretFor(ProxyAccessible *aProxy,
175                                    const LayoutDeviceIntRect &aCaretRect);
176 
177  private:
178   static void UpdateSystemCaretFor(HWND aCaretWnd,
179                                    const LayoutDeviceIntRect &aCaretRect);
180 
181  public:
182   /**
183    * Determine whether this is the root accessible for its HWND.
184    */
185   bool IsRootForHWND();
186 
187   /**
188    * Find an accessible by the given child ID in cached documents.
189    */
190   MOZ_MUST_USE already_AddRefed<IAccessible> GetIAccessibleFor(
191       const VARIANT &aVarChild, bool *aIsDefunct);
192 
193   virtual void GetNativeInterface(void **aOutAccessible) override;
194 
195   static IDispatch *NativeAccessible(Accessible *aAccessible);
196 
GetExistingID()197   uint32_t GetExistingID() const { return mID; }
198   static const uint32_t kNoID = 0;
199   void SetID(uint32_t aID);
200 
201   static uint32_t GetContentProcessIdFor(dom::ContentParentId aIPCContentId);
202   static void ReleaseContentProcessIdFor(dom::ContentParentId aIPCContentId);
203 
204   static void SetHandlerControl(DWORD aPid, RefPtr<IHandlerControl> aCtrl);
205 
206   static void InvalidateHandlers();
207 
208   bool DispatchTextChangeToHandler(bool aIsInsert, const nsString &aText,
209                                    int32_t aStart, uint32_t aLen);
210 
211   static void AssignChildIDTo(NotNull<sdnAccessible *> aSdnAcc);
212   static void ReleaseChildID(NotNull<sdnAccessible *> aSdnAcc);
213 
214  protected:
215   virtual ~AccessibleWrap();
216 
217   uint32_t mID;
218 
219   HRESULT
220   ResolveChild(const VARIANT &aVarChild, IAccessible **aOutInterface);
221 
222   /**
223    * Find a remote accessible by the given child ID.
224    */
225   MOZ_MUST_USE already_AddRefed<IAccessible> GetRemoteIAccessibleFor(
226       const VARIANT &aVarChild);
227 
228   /**
229    * Return the wrapper for the document's proxy.
230    */
231   DocProxyAccessibleWrap *DocProxyWrapper() const;
232 
233   /**
234    * Creates ITypeInfo for LIBID_Accessibility if it's needed and returns it.
235    */
236   static ITypeInfo *GetTI(LCID lcid);
237 
238   static ITypeInfo *gTypeInfo;
239 
240   static MsaaIdGenerator sIDGen;
241 
242   enum navRelations {
243     NAVRELATION_CONTROLLED_BY = 0x1000,
244     NAVRELATION_CONTROLLER_FOR = 0x1001,
245     NAVRELATION_LABEL_FOR = 0x1002,
246     NAVRELATION_LABELLED_BY = 0x1003,
247     NAVRELATION_MEMBER_OF = 0x1004,
248     NAVRELATION_NODE_CHILD_OF = 0x1005,
249     NAVRELATION_FLOWS_TO = 0x1006,
250     NAVRELATION_FLOWS_FROM = 0x1007,
251     NAVRELATION_SUBWINDOW_OF = 0x1008,
252     NAVRELATION_EMBEDS = 0x1009,
253     NAVRELATION_EMBEDDED_BY = 0x100a,
254     NAVRELATION_POPUP_FOR = 0x100b,
255     NAVRELATION_PARENT_WINDOW_OF = 0x100c,
256     NAVRELATION_DEFAULT_BUTTON = 0x100d,
257     NAVRELATION_DESCRIBED_BY = 0x100e,
258     NAVRELATION_DESCRIPTION_FOR = 0x100f,
259     NAVRELATION_NODE_PARENT_OF = 0x1010,
260     NAVRELATION_CONTAINING_DOCUMENT = 0x1011,
261     NAVRELATION_CONTAINING_TAB_PANE = 0x1012,
262     NAVRELATION_CONTAINING_WINDOW = 0x1013,
263     NAVRELATION_CONTAINING_APPLICATION = 0x1014,
264     NAVRELATION_DETAILS = 0x1015,
265     NAVRELATION_DETAILS_FOR = 0x1016,
266     NAVRELATION_ERROR = 0x1017,
267     NAVRELATION_ERROR_FOR = 0x1018
268   };
269 
270   struct HandlerControllerData final {
HandlerControllerDatafinal271     HandlerControllerData(DWORD aPid, RefPtr<IHandlerControl> &&aCtrl)
272         : mPid(aPid), mCtrl(Move(aCtrl)) {
273       mIsProxy = mozilla::mscom::IsProxy(mCtrl);
274     }
275 
HandlerControllerDatafinal276     HandlerControllerData(HandlerControllerData &&aOther)
277         : mPid(aOther.mPid),
278           mIsProxy(aOther.mIsProxy),
279           mCtrl(Move(aOther.mCtrl)) {}
280 
281     bool operator==(const HandlerControllerData &aOther) const {
282       return mPid == aOther.mPid;
283     }
284 
285     bool operator==(const DWORD &aPid) const { return mPid == aPid; }
286 
287     DWORD mPid;
288     bool mIsProxy;
289     RefPtr<IHandlerControl> mCtrl;
290   };
291 
292   static StaticAutoPtr<nsTArray<HandlerControllerData>> sHandlerControllers;
293 };
294 
WrapperFor(const ProxyAccessible * aProxy)295 static inline AccessibleWrap *WrapperFor(const ProxyAccessible *aProxy) {
296   return reinterpret_cast<AccessibleWrap *>(aProxy->GetWrapper());
297 }
298 
299 }  // namespace a11y
300 }  // namespace mozilla
301 
302 #ifdef XP_WIN
303 // Undo the windows.h damage
304 #undef GetMessage
305 #undef CreateEvent
306 #undef GetClassName
307 #undef GetBinaryType
308 #undef RemoveDirectory
309 #endif
310 
311 #endif
312