summaryrefslogtreecommitdiffstats
path: root/accessible/ipc/win/handler/AccessibleHandlerControl.h
blob: d016ecb98b0ed3cb53336a5bc1a75e628f1c69fc (plain)
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
/* -*- 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/. */

#if defined(MOZILLA_INTERNAL_API)
#  error This code is NOT for internal Gecko use!
#endif  // defined(MOZILLA_INTERNAL_API)

#ifndef mozilla_a11y_AccessibleHandlerControl_h
#  define mozilla_a11y_AccessibleHandlerControl_h

#  include <unordered_map>
#  include "Factory.h"
#  include "HandlerData.h"
#  include "IUnknownImpl.h"
#  include "mozilla/mscom/Registration.h"
#  include "mozilla/NotNull.h"

namespace mozilla {
namespace a11y {

namespace detail {

class TextChange final {
 public:
  TextChange();
  TextChange(long aIA2UniqueId, bool aIsInsert, NotNull<IA2TextSegment*> aText);
  TextChange(TextChange&& aOther);
  TextChange(const TextChange& aOther);

  TextChange& operator=(TextChange&& aOther);
  TextChange& operator=(const TextChange& aOther);

  ~TextChange();

  HRESULT GetOld(long aIA2UniqueId, NotNull<IA2TextSegment*> aOutOldSegment);
  HRESULT GetNew(long aIA2UniqueId, NotNull<IA2TextSegment*> aOutNewSegment);

 private:
  static BSTR BSTRCopy(const BSTR& aIn);
  static HRESULT SegCopy(IA2TextSegment& aDest, const IA2TextSegment& aSrc);

  long mIA2UniqueId;
  bool mIsInsert;
  IA2TextSegment mText;
};

}  // namespace detail

class AccessibleHandler;

class AccessibleHandlerControl final : public IHandlerControl {
 public:
  static HRESULT Create(AccessibleHandlerControl** aOutObject);

  DECL_IUNKNOWN

  // IHandlerControl
  STDMETHODIMP Invalidate() override;
  STDMETHODIMP OnTextChange(long aHwnd, long aIA2UniqueId,
                            VARIANT_BOOL aIsInsert,
                            IA2TextSegment* aText) override;

  uint32_t GetCacheGen() const { return mCacheGen; }

  HRESULT GetNewText(long aIA2UniqueId, NotNull<IA2TextSegment*> aOutNewText);
  HRESULT GetOldText(long aIA2UniqueId, NotNull<IA2TextSegment*> aOutOldText);

  HRESULT GetHandlerTypeInfo(ITypeInfo** aOutTypeInfo);

  HRESULT Register(NotNull<IGeckoBackChannel*> aGecko);

  void CacheAccessible(long aUniqueId, AccessibleHandler* aAccessible);
  HRESULT GetCachedAccessible(long aUniqueId, AccessibleHandler** aAccessible);

 private:
  AccessibleHandlerControl();
  ~AccessibleHandlerControl() = default;

  bool mIsRegistered;
  uint32_t mCacheGen;
  detail::TextChange mTextChange;
  UniquePtr<mscom::RegisteredProxy> mIA2Proxy;
  UniquePtr<mscom::RegisteredProxy> mHandlerProxy;
  // We can't use Gecko APIs in this dll, hence the use of std::unordered_map.
  typedef std::unordered_map<long, RefPtr<AccessibleHandler>> AccessibleCache;
  AccessibleCache mAccessibleCache;
};

extern mscom::SingletonFactory<AccessibleHandlerControl> gControlFactory;

}  // namespace a11y
}  // namespace mozilla

#endif  // mozilla_a11y_AccessibleHandlerControl_h