diff options
Diffstat (limited to '')
-rw-r--r-- | accessible/windows/msaa/IUnknownImpl.h | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/accessible/windows/msaa/IUnknownImpl.h b/accessible/windows/msaa/IUnknownImpl.h new file mode 100644 index 0000000000..7935ebedda --- /dev/null +++ b/accessible/windows/msaa/IUnknownImpl.h @@ -0,0 +1,173 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=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_IUnknownImpl_h_ +#define mozilla_a11y_IUnknownImpl_h_ + +#include <windows.h> +#undef CreateEvent // thank you windows you're such a helper +#include "nsError.h" + +// Avoid warning C4509 like "nonstandard extension used: +// 'AccessibleWrap::[acc_getName]' uses SEH and 'name' has destructor. +// At this point we're catching a crash which is of much greater +// importance than the missing dereference for the nsCOMPtr<> +#ifdef _MSC_VER +# pragma warning(disable : 4509) +#endif + +#if defined(__GNUC__) || defined(__clang__) +# define ATTRIBUTE_UNUSED __attribute__((unused)) +#else +# define ATTRIBUTE_UNUSED +#endif + +namespace mozilla { +namespace a11y { + +class AutoRefCnt { + public: + AutoRefCnt() : mValue(0) {} + + ULONG operator++() { return ++mValue; } + ULONG operator--() { return --mValue; } + ULONG operator++(int) { return ++mValue; } + ULONG operator--(int) { return --mValue; } + + operator ULONG() const { return mValue; } + + private: + ULONG mValue; +}; + +} // namespace a11y +} // namespace mozilla + +#define DECL_IUNKNOWN \ + public: \ + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, void**); \ + ULONG STDMETHODCALLTYPE AddRef() override { \ + MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt"); \ + ++mRefCnt; \ + return mRefCnt; \ + } \ + ULONG STDMETHODCALLTYPE Release() override { \ + MOZ_ASSERT(int32_t(mRefCnt) > 0, "dup release"); \ + --mRefCnt; \ + if (mRefCnt) return mRefCnt; \ + \ + delete this; \ + return 0; \ + } \ + \ + private: \ + mozilla::a11y::AutoRefCnt mRefCnt; \ + \ + public: + +#define DECL_IUNKNOWN_INHERITED \ + public: \ + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, void**); + +#define IMPL_IUNKNOWN_QUERY_HEAD(Class) \ + STDMETHODIMP \ + Class::QueryInterface(REFIID aIID, void** aInstancePtr) { \ + if (!aInstancePtr) return E_INVALIDARG; \ + *aInstancePtr = nullptr; \ + \ + HRESULT hr ATTRIBUTE_UNUSED = E_NOINTERFACE; + +#define IMPL_IUNKNOWN_QUERY_TAIL \ + return hr; \ + } + +#define IMPL_IUNKNOWN_QUERY_TAIL_AGGREGATED(Member) \ + return Member->QueryInterface(aIID, aInstancePtr); \ + } + +#define IMPL_IUNKNOWN_QUERY_TAIL_INHERITED(BaseClass) \ + return BaseClass::QueryInterface(aIID, aInstancePtr); \ + } + +#define IMPL_IUNKNOWN_QUERY_IFACE(Iface) \ + if (aIID == IID_##Iface) { \ + *aInstancePtr = static_cast<Iface*>(this); \ + AddRef(); \ + return S_OK; \ + } + +#define IMPL_IUNKNOWN_QUERY_IFACE_AMBIGIOUS(Iface, aResolveIface) \ + if (aIID == IID_##Iface) { \ + *aInstancePtr = static_cast<Iface*>(static_cast<aResolveIface*>(this)); \ + AddRef(); \ + return S_OK; \ + } + +#define IMPL_IUNKNOWN_QUERY_CLASS(Class) \ + hr = Class::QueryInterface(aIID, aInstancePtr); \ + if (SUCCEEDED(hr)) return hr; + +#define IMPL_IUNKNOWN_QUERY_CLASS_COND(Class, Cond) \ + if (Cond) { \ + hr = Class::QueryInterface(aIID, aInstancePtr); \ + if (SUCCEEDED(hr)) return hr; \ + } + +#define IMPL_IUNKNOWN_QUERY_AGGR_COND(Member, Cond) \ + if (Cond) { \ + hr = Member->QueryInterface(aIID, aInstancePtr); \ + if (SUCCEEDED(hr)) return hr; \ + } + +#define IMPL_IUNKNOWN1(Class, I1) \ + IMPL_IUNKNOWN_QUERY_HEAD(Class) \ + IMPL_IUNKNOWN_QUERY_IFACE(I1); \ + IMPL_IUNKNOWN_QUERY_IFACE(IUnknown); \ + IMPL_IUNKNOWN_QUERY_TAIL + +#define IMPL_IUNKNOWN2(Class, I1, I2) \ + IMPL_IUNKNOWN_QUERY_HEAD(Class) \ + IMPL_IUNKNOWN_QUERY_IFACE(I1); \ + IMPL_IUNKNOWN_QUERY_IFACE(I2); \ + IMPL_IUNKNOWN_QUERY_IFACE_AMBIGIOUS(IUnknown, I1); \ + IMPL_IUNKNOWN_QUERY_TAIL + +#define IMPL_IUNKNOWN_INHERITED1(Class, Super0, Super1) \ + IMPL_IUNKNOWN_QUERY_HEAD(Class) \ + IMPL_IUNKNOWN_QUERY_CLASS(Super1); \ + IMPL_IUNKNOWN_QUERY_TAIL_INHERITED(Super0) + +#define IMPL_IUNKNOWN_INHERITED2(Class, Super0, Super1, Super2) \ + IMPL_IUNKNOWN_QUERY_HEAD(Class) \ + IMPL_IUNKNOWN_QUERY_CLASS(Super1); \ + IMPL_IUNKNOWN_QUERY_CLASS(Super2); \ + IMPL_IUNKNOWN_QUERY_TAIL_INHERITED(Super0) + +/** + * Overrides AddRef and Release to call a specific base class. + * If you are inheriting a single class (e.g. to override some methods), you + * shouldn't need to use this. However, if you are inheriting from a COM + * implementation and also inheriting additional COM interfaces, you will need + * to use this to specify which base implements reference counting. + */ +#define IMPL_IUNKNOWN_REFCOUNTING_INHERITED(BaseClass) \ + public: \ + ULONG STDMETHODCALLTYPE AddRef() override { return BaseClass::AddRef(); } \ + ULONG STDMETHODCALLTYPE Release() override { return BaseClass::Release(); } + +namespace mozilla { +namespace a11y { + +/** + * Converts nsresult to HRESULT. + */ +HRESULT GetHRESULT(nsresult aResult); + +} // namespace a11y +} // namespace mozilla + +#endif |