summaryrefslogtreecommitdiffstats
path: root/accessible/windows/msaa/IUnknownImpl.h
diff options
context:
space:
mode:
Diffstat (limited to 'accessible/windows/msaa/IUnknownImpl.h')
-rw-r--r--accessible/windows/msaa/IUnknownImpl.h192
1 files changed, 192 insertions, 0 deletions
diff --git a/accessible/windows/msaa/IUnknownImpl.h b/accessible/windows/msaa/IUnknownImpl.h
new file mode 100644
index 000000000..dbf6c1374
--- /dev/null
+++ b/accessible/windows/msaa/IUnknownImpl.h
@@ -0,0 +1,192 @@
+/* -*- 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
+
+#ifdef __GNUC__
+#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**); \
+ virtual ULONG STDMETHODCALLTYPE AddRef() final \
+ { \
+ MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt"); \
+ ++mRefCnt; \
+ return mRefCnt; \
+ } \
+ virtual ULONG STDMETHODCALLTYPE Release() final \
+ { \
+ 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) \
+{ \
+ A11Y_TRYBLOCK_BEGIN \
+ if (!aInstancePtr) \
+ return E_INVALIDARG; \
+ *aInstancePtr = nullptr; \
+ \
+ HRESULT hr ATTRIBUTE_UNUSED = E_NOINTERFACE;
+
+#define IMPL_IUNKNOWN_QUERY_TAIL \
+ return hr; \
+ A11Y_TRYBLOCK_END \
+}
+
+#define IMPL_IUNKNOWN_QUERY_TAIL_AGGREGATED(Member) \
+ return Member->QueryInterface(aIID, aInstancePtr); \
+ A11Y_TRYBLOCK_END \
+}
+
+#define IMPL_IUNKNOWN_QUERY_TAIL_INHERITED(BaseClass) \
+ return BaseClass::QueryInterface(aIID, aInstancePtr); \
+ A11Y_TRYBLOCK_END \
+}
+
+#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)
+
+
+/**
+ * Wrap every method body by these macroses to pass exception to the crash
+ * reporter.
+ */
+#define A11Y_TRYBLOCK_BEGIN \
+ MOZ_SEH_TRY {
+
+#define A11Y_TRYBLOCK_END \
+ } MOZ_SEH_EXCEPT(mozilla::a11y::FilterExceptions(::GetExceptionCode(), \
+ GetExceptionInformation())) \
+ { } \
+ return E_FAIL;
+
+
+namespace mozilla {
+namespace a11y {
+
+/**
+ * Converts nsresult to HRESULT.
+ */
+HRESULT GetHRESULT(nsresult aResult);
+
+/**
+ * Used to pass an exception to the crash reporter.
+ */
+int FilterExceptions(unsigned int aCode, EXCEPTION_POINTERS* aExceptionInfo);
+
+} // namespace a11y;
+} //namespace mozilla;
+
+#endif