ia2AccessibleAction.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* vim:expandtab:shiftwidth=2:tabstop=2:
  3. */
  4. /* This Source Code Form is subject to the terms of the Mozilla Public
  5. * License, v. 2.0. If a copy of the MPL was not distributed with this
  6. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  7. #include "ia2AccessibleAction.h"
  8. #include "AccessibleAction_i.c"
  9. #include "AccessibleWrap.h"
  10. #include "IUnknownImpl.h"
  11. using namespace mozilla::a11y;
  12. // IUnknown
  13. STDMETHODIMP
  14. ia2AccessibleAction::QueryInterface(REFIID iid, void** ppv)
  15. {
  16. if (!ppv)
  17. return E_INVALIDARG;
  18. *ppv = nullptr;
  19. if (IID_IAccessibleAction == iid &&
  20. !static_cast<AccessibleWrap*>(this)->IsProxy()) {
  21. *ppv = static_cast<IAccessibleAction*>(this);
  22. (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
  23. return S_OK;
  24. }
  25. return E_NOINTERFACE;
  26. }
  27. // IAccessibleAction
  28. STDMETHODIMP
  29. ia2AccessibleAction::nActions(long* aActionCount)
  30. {
  31. if (!aActionCount)
  32. return E_INVALIDARG;
  33. *aActionCount = 0;
  34. AccessibleWrap* acc = static_cast<AccessibleWrap*>(this);
  35. if (acc->IsDefunct())
  36. return CO_E_OBJNOTCONNECTED;
  37. *aActionCount = acc->ActionCount();
  38. return S_OK;
  39. }
  40. STDMETHODIMP
  41. ia2AccessibleAction::doAction(long aActionIndex)
  42. {
  43. AccessibleWrap* acc = static_cast<AccessibleWrap*>(this);
  44. if (acc->IsDefunct())
  45. return CO_E_OBJNOTCONNECTED;
  46. uint8_t index = static_cast<uint8_t>(aActionIndex);
  47. return acc->DoAction(index) ? S_OK : E_INVALIDARG;
  48. }
  49. STDMETHODIMP
  50. ia2AccessibleAction::get_description(long aActionIndex, BSTR *aDescription)
  51. {
  52. if (!aDescription)
  53. return E_INVALIDARG;
  54. *aDescription = nullptr;
  55. AccessibleWrap* acc = static_cast<AccessibleWrap*>(this);
  56. if (acc->IsDefunct())
  57. return CO_E_OBJNOTCONNECTED;
  58. nsAutoString description;
  59. uint8_t index = static_cast<uint8_t>(aActionIndex);
  60. acc->ActionDescriptionAt(index, description);
  61. if (description.IsEmpty())
  62. return S_FALSE;
  63. *aDescription = ::SysAllocStringLen(description.get(),
  64. description.Length());
  65. return *aDescription ? S_OK : E_OUTOFMEMORY;
  66. }
  67. STDMETHODIMP
  68. ia2AccessibleAction::get_keyBinding(long aActionIndex, long aNumMaxBinding,
  69. BSTR **aKeyBinding,
  70. long *aNumBinding)
  71. {
  72. if (!aKeyBinding)
  73. return E_INVALIDARG;
  74. *aKeyBinding = nullptr;
  75. if (!aNumBinding)
  76. return E_INVALIDARG;
  77. *aNumBinding = 0;
  78. if (aActionIndex != 0 || aNumMaxBinding < 1)
  79. return E_INVALIDARG;
  80. AccessibleWrap* acc = static_cast<AccessibleWrap*>(this);
  81. if (acc->IsDefunct())
  82. return CO_E_OBJNOTCONNECTED;
  83. // Expose keyboard shortcut if it's not exposed via MSAA keyboard shortcut.
  84. KeyBinding keyBinding = acc->AccessKey();
  85. if (keyBinding.IsEmpty())
  86. return S_FALSE;
  87. keyBinding = acc->KeyboardShortcut();
  88. if (keyBinding.IsEmpty())
  89. return S_FALSE;
  90. nsAutoString keyStr;
  91. keyBinding.ToString(keyStr);
  92. *aKeyBinding = static_cast<BSTR*>(::CoTaskMemAlloc(sizeof(BSTR*)));
  93. if (!*aKeyBinding)
  94. return E_OUTOFMEMORY;
  95. *(aKeyBinding[0]) = ::SysAllocStringLen(keyStr.get(), keyStr.Length());
  96. if (!*(aKeyBinding[0])) {
  97. ::CoTaskMemFree(*aKeyBinding);
  98. return E_OUTOFMEMORY;
  99. }
  100. *aNumBinding = 1;
  101. return S_OK;
  102. }
  103. STDMETHODIMP
  104. ia2AccessibleAction::get_name(long aActionIndex, BSTR *aName)
  105. {
  106. if (!aName)
  107. return E_INVALIDARG;
  108. *aName = nullptr;
  109. AccessibleWrap* acc = static_cast<AccessibleWrap*>(this);
  110. if (acc->IsDefunct())
  111. return CO_E_OBJNOTCONNECTED;
  112. nsAutoString name;
  113. uint8_t index = static_cast<uint8_t>(aActionIndex);
  114. acc->ActionNameAt(index, name);
  115. if (name.IsEmpty())
  116. return E_INVALIDARG;
  117. *aName = ::SysAllocStringLen(name.get(), name.Length());
  118. return *aName ? S_OK : E_OUTOFMEMORY;
  119. }
  120. STDMETHODIMP
  121. ia2AccessibleAction::get_localizedName(long aActionIndex, BSTR *aLocalizedName)
  122. {
  123. if (!aLocalizedName)
  124. return E_INVALIDARG;
  125. *aLocalizedName = nullptr;
  126. return E_NOTIMPL;
  127. }