diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /accessible/ipc/win | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'accessible/ipc/win')
-rw-r--r-- | accessible/ipc/win/COMPtrTypes.cpp | 50 | ||||
-rw-r--r-- | accessible/ipc/win/COMPtrTypes.h | 27 | ||||
-rw-r--r-- | accessible/ipc/win/DocAccessibleChild.cpp | 237 | ||||
-rw-r--r-- | accessible/ipc/win/DocAccessibleChild.h | 318 | ||||
-rw-r--r-- | accessible/ipc/win/PDocAccessible.ipdl | 75 | ||||
-rw-r--r-- | accessible/ipc/win/PlatformChild.cpp | 62 | ||||
-rw-r--r-- | accessible/ipc/win/PlatformChild.h | 35 | ||||
-rw-r--r-- | accessible/ipc/win/ProxyAccessible.cpp | 599 | ||||
-rw-r--r-- | accessible/ipc/win/ProxyAccessible.h | 58 | ||||
-rw-r--r-- | accessible/ipc/win/moz.build | 39 | ||||
-rw-r--r-- | accessible/ipc/win/typelib/Accessible.idl | 16 | ||||
-rw-r--r-- | accessible/ipc/win/typelib/Makefile.in | 31 | ||||
-rw-r--r-- | accessible/ipc/win/typelib/moz.build | 13 |
13 files changed, 1560 insertions, 0 deletions
diff --git a/accessible/ipc/win/COMPtrTypes.cpp b/accessible/ipc/win/COMPtrTypes.cpp new file mode 100644 index 000000000..857f4235e --- /dev/null +++ b/accessible/ipc/win/COMPtrTypes.cpp @@ -0,0 +1,50 @@ +/* -*- 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/. */ + +#include "mozilla/a11y/COMPtrTypes.h" + +#include "MainThreadUtils.h" +#include "mozilla/a11y/Accessible.h" +#include "mozilla/Move.h" +#include "mozilla/mscom/MainThreadHandoff.h" +#include "mozilla/RefPtr.h" + +using mozilla::mscom::MainThreadHandoff; +using mozilla::mscom::STAUniquePtr; + +namespace mozilla { +namespace a11y { + +IAccessibleHolder +CreateHolderFromAccessible(Accessible* aAccToWrap) +{ + MOZ_ASSERT(aAccToWrap && NS_IsMainThread()); + if (!aAccToWrap) { + return nullptr; + } + + IAccessible* rawNative = nullptr; + aAccToWrap->GetNativeInterface((void**)&rawNative); + MOZ_ASSERT(rawNative); + if (!rawNative) { + return nullptr; + } + + STAUniquePtr<IAccessible> iaToProxy(rawNative); + + IAccessible* rawIntercepted = nullptr; + HRESULT hr = MainThreadHandoff::WrapInterface(Move(iaToProxy), &rawIntercepted); + MOZ_ASSERT(SUCCEEDED(hr)); + if (FAILED(hr)) { + return nullptr; + } + + IAccessibleHolder::COMPtrType iaIntercepted(rawIntercepted); + return IAccessibleHolder(Move(iaIntercepted)); +} + +} // namespace a11y +} // namespace mozilla diff --git a/accessible/ipc/win/COMPtrTypes.h b/accessible/ipc/win/COMPtrTypes.h new file mode 100644 index 000000000..122e1ea5e --- /dev/null +++ b/accessible/ipc/win/COMPtrTypes.h @@ -0,0 +1,27 @@ +/* -*- 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_COMPtrTypes_h +#define mozilla_a11y_COMPtrTypes_h + +#include "mozilla/mscom/COMPtrHolder.h" + +#include <oleacc.h> + +namespace mozilla { +namespace a11y { + +typedef mozilla::mscom::COMPtrHolder<IAccessible, IID_IAccessible> IAccessibleHolder; + +class Accessible; + +IAccessibleHolder +CreateHolderFromAccessible(Accessible* aAccToWrap); + +} // namespace a11y +} // namespace mozilla + +#endif // mozilla_a11y_COMPtrTypes_h diff --git a/accessible/ipc/win/DocAccessibleChild.cpp b/accessible/ipc/win/DocAccessibleChild.cpp new file mode 100644 index 000000000..e8b8bebe5 --- /dev/null +++ b/accessible/ipc/win/DocAccessibleChild.cpp @@ -0,0 +1,237 @@ +/* -*- 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/. */ + +#include "DocAccessibleChild.h" + +#include "Accessible-inl.h" +#include "mozilla/a11y/PlatformChild.h" +#include "mozilla/ClearOnShutdown.h" +#include "RootAccessible.h" + +namespace mozilla { +namespace a11y { + +static StaticAutoPtr<PlatformChild> sPlatformChild; + +DocAccessibleChild::DocAccessibleChild(DocAccessible* aDoc) + : DocAccessibleChildBase(aDoc) + , mIsRemoteConstructed(false) +{ + MOZ_COUNT_CTOR_INHERITED(DocAccessibleChild, DocAccessibleChildBase); + if (!sPlatformChild) { + sPlatformChild = new PlatformChild(); + ClearOnShutdown(&sPlatformChild, ShutdownPhase::Shutdown); + } +} + +DocAccessibleChild::~DocAccessibleChild() +{ + MOZ_COUNT_DTOR_INHERITED(DocAccessibleChild, DocAccessibleChildBase); +} + +void +DocAccessibleChild::Shutdown() +{ + if (IsConstructedInParentProcess()) { + DocAccessibleChildBase::Shutdown(); + return; + } + + PushDeferredEvent(MakeUnique<SerializedShutdown>(this)); + DetachDocument(); +} + +bool +DocAccessibleChild::RecvParentCOMProxy(const IAccessibleHolder& aParentCOMProxy) +{ + MOZ_ASSERT(!mParentProxy && !aParentCOMProxy.IsNull()); + mParentProxy.reset(const_cast<IAccessibleHolder&>(aParentCOMProxy).Release()); + SetConstructedInParentProcess(); + + for (uint32_t i = 0, l = mDeferredEvents.Length(); i < l; ++i) { + mDeferredEvents[i]->Dispatch(); + } + + mDeferredEvents.Clear(); + + return true; +} + +void +DocAccessibleChild::PushDeferredEvent(UniquePtr<DeferredEvent> aEvent) +{ + DocAccessibleChild* topLevelIPCDoc = nullptr; + + if (mDoc && mDoc->IsRoot()) { + topLevelIPCDoc = this; + } else { + auto tabChild = static_cast<dom::TabChild*>(Manager()); + if (!tabChild) { + return; + } + + nsTArray<PDocAccessibleChild*> ipcDocAccs; + tabChild->ManagedPDocAccessibleChild(ipcDocAccs); + + // Look for the top-level DocAccessibleChild - there will only be one + // per TabChild. + for (uint32_t i = 0, l = ipcDocAccs.Length(); i < l; ++i) { + auto ipcDocAcc = static_cast<DocAccessibleChild*>(ipcDocAccs[i]); + if (ipcDocAcc->mDoc && ipcDocAcc->mDoc->IsRoot()) { + topLevelIPCDoc = ipcDocAcc; + break; + } + } + } + + if (topLevelIPCDoc) { + topLevelIPCDoc->mDeferredEvents.AppendElement(Move(aEvent)); + } +} + +bool +DocAccessibleChild::SendEvent(const uint64_t& aID, const uint32_t& aType) +{ + if (IsConstructedInParentProcess()) { + return PDocAccessibleChild::SendEvent(aID, aType); + } + + PushDeferredEvent(MakeUnique<SerializedEvent>(this, aID, aType)); + return false; +} + +void +DocAccessibleChild::MaybeSendShowEvent(ShowEventData& aData, bool aFromUser) +{ + if (IsConstructedInParentProcess()) { + Unused << SendShowEvent(aData, aFromUser); + return; + } + + PushDeferredEvent(MakeUnique<SerializedShow>(this, aData, aFromUser)); +} + +bool +DocAccessibleChild::SendHideEvent(const uint64_t& aRootID, + const bool& aFromUser) +{ + if (IsConstructedInParentProcess()) { + return PDocAccessibleChild::SendHideEvent(aRootID, aFromUser); + } + + PushDeferredEvent(MakeUnique<SerializedHide>(this, aRootID, aFromUser)); + return true; +} + +bool +DocAccessibleChild::SendStateChangeEvent(const uint64_t& aID, + const uint64_t& aState, + const bool& aEnabled) +{ + if (IsConstructedInParentProcess()) { + return PDocAccessibleChild::SendStateChangeEvent(aID, aState, aEnabled); + } + + PushDeferredEvent(MakeUnique<SerializedStateChange>(this, aID, aState, + aEnabled)); + return true; +} + +bool +DocAccessibleChild::SendCaretMoveEvent(const uint64_t& aID, + const int32_t& aOffset) +{ + if (IsConstructedInParentProcess()) { + return PDocAccessibleChild::SendCaretMoveEvent(aID, aOffset); + } + + PushDeferredEvent(MakeUnique<SerializedCaretMove>(this, aID, aOffset)); + return true; +} + +bool +DocAccessibleChild::SendTextChangeEvent(const uint64_t& aID, + const nsString& aStr, + const int32_t& aStart, + const uint32_t& aLen, + const bool& aIsInsert, + const bool& aFromUser) +{ + if (IsConstructedInParentProcess()) { + return PDocAccessibleChild::SendTextChangeEvent(aID, aStr, aStart, + aLen, aIsInsert, aFromUser); + } + + PushDeferredEvent(MakeUnique<SerializedTextChange>(this, aID, aStr, aStart, + aLen, aIsInsert, aFromUser)); + return true; +} + +bool +DocAccessibleChild::SendSelectionEvent(const uint64_t& aID, + const uint64_t& aWidgetID, + const uint32_t& aType) +{ + if (IsConstructedInParentProcess()) { + return PDocAccessibleChild::SendSelectionEvent(aID, aWidgetID, aType); + } + + PushDeferredEvent(MakeUnique<SerializedSelection>(this, aID, + aWidgetID, + aType)); + return true; +} + +bool +DocAccessibleChild::SendRoleChangedEvent(const uint32_t& aRole) +{ + if (IsConstructedInParentProcess()) { + return PDocAccessibleChild::SendRoleChangedEvent(aRole); + } + + PushDeferredEvent(MakeUnique<SerializedRoleChanged>(this, aRole)); + return true; +} + +bool +DocAccessibleChild::ConstructChildDocInParentProcess( + DocAccessibleChild* aNewChildDoc, + uint64_t aUniqueID, uint32_t aMsaaID) +{ + if (IsConstructedInParentProcess()) { + // We may send the constructor immediately + auto tabChild = static_cast<dom::TabChild*>(Manager()); + MOZ_ASSERT(tabChild); + bool result = tabChild->SendPDocAccessibleConstructor(aNewChildDoc, this, + aUniqueID, aMsaaID, + IAccessibleHolder()); + if (result) { + aNewChildDoc->SetConstructedInParentProcess(); + } + return result; + } + + PushDeferredEvent(MakeUnique<SerializedChildDocConstructor>(aNewChildDoc, this, + aUniqueID, aMsaaID)); + return true; +} + +bool +DocAccessibleChild::SendBindChildDoc(DocAccessibleChild* aChildDoc, + const uint64_t& aNewParentID) +{ + if (IsConstructedInParentProcess()) { + return DocAccessibleChildBase::SendBindChildDoc(aChildDoc, aNewParentID); + } + + PushDeferredEvent(MakeUnique<SerializedBindChildDoc>(this, aChildDoc, + aNewParentID)); + return true; +} + +} // namespace a11y +} // namespace mozilla + diff --git a/accessible/ipc/win/DocAccessibleChild.h b/accessible/ipc/win/DocAccessibleChild.h new file mode 100644 index 000000000..7a3da0172 --- /dev/null +++ b/accessible/ipc/win/DocAccessibleChild.h @@ -0,0 +1,318 @@ +/* -*- 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_DocAccessibleChild_h +#define mozilla_a11y_DocAccessibleChild_h + +#include "mozilla/a11y/COMPtrTypes.h" +#include "mozilla/a11y/DocAccessibleChildBase.h" +#include "mozilla/dom/TabChild.h" +#include "mozilla/mscom/Ptr.h" + +namespace mozilla { +namespace a11y { + +/* + * These objects handle content side communication for an accessible document, + * and their lifetime is the same as the document they represent. + */ +class DocAccessibleChild : public DocAccessibleChildBase +{ +public: + explicit DocAccessibleChild(DocAccessible* aDoc); + ~DocAccessibleChild(); + + virtual void Shutdown() override; + + virtual bool + RecvParentCOMProxy(const IAccessibleHolder& aParentCOMProxy) override; + + IAccessible* GetParentIAccessible() const { return mParentProxy.get(); } + + bool SendEvent(const uint64_t& aID, const uint32_t& type); + bool SendHideEvent(const uint64_t& aRootID, const bool& aFromUser); + bool SendStateChangeEvent(const uint64_t& aID, const uint64_t& aState, + const bool& aEnabled); + bool SendCaretMoveEvent(const uint64_t& aID, const int32_t& aOffset); + bool SendTextChangeEvent(const uint64_t& aID, const nsString& aStr, + const int32_t& aStart, const uint32_t& aLen, + const bool& aIsInsert, const bool& aFromUser); + bool SendSelectionEvent(const uint64_t& aID, const uint64_t& aWidgetID, + const uint32_t& aType); + bool SendRoleChangedEvent(const uint32_t& aRole); + + bool ConstructChildDocInParentProcess(DocAccessibleChild* aNewChildDoc, + uint64_t aUniqueID, uint32_t aMsaaID); + + bool SendBindChildDoc(DocAccessibleChild* aChildDoc, + const uint64_t& aNewParentID); + +protected: + virtual void MaybeSendShowEvent(ShowEventData& aData, bool aFromUser) override; + +private: + void RemoveDeferredConstructor(); + + bool IsConstructedInParentProcess() const { return mIsRemoteConstructed; } + void SetConstructedInParentProcess() { mIsRemoteConstructed = true; } + + /** + * DocAccessibleChild should not fire events until it has asynchronously + * received the COM proxy for its parent. OTOH, content a11y may still be + * attempting to fire events during this window of time. If this object does + * not yet have its parent proxy, instead of immediately sending the events to + * our parent, we enqueue them to mDeferredEvents. As soon as + * RecvParentCOMProxy is called, we play back mDeferredEvents. + */ + struct DeferredEvent + { + void Dispatch() + { + Dispatch(mTarget); + } + + virtual ~DeferredEvent() {} + + protected: + explicit DeferredEvent(DocAccessibleChild* aTarget) + : mTarget(aTarget) + {} + + virtual void Dispatch(DocAccessibleChild* aIPCDoc) = 0; + + private: + DocAccessibleChild* mTarget; + }; + + void PushDeferredEvent(UniquePtr<DeferredEvent> aEvent); + + struct SerializedShow final : public DeferredEvent + { + SerializedShow(DocAccessibleChild* aTarget, + ShowEventData& aEventData, bool aFromUser) + : DeferredEvent(aTarget) + , mEventData(aEventData.ID(), aEventData.Idx(), nsTArray<AccessibleData>()) + , mFromUser(aFromUser) + { + // Since IPDL doesn't generate a move constructor for ShowEventData, + // we move NewTree manually (ugh). We still construct with an empty + // NewTree above so that the compiler catches any changes made to the + // ShowEventData structure in IPDL. + mEventData.NewTree() = Move(aEventData.NewTree()); + } + + void Dispatch(DocAccessibleChild* aIPCDoc) override + { + Unused << aIPCDoc->SendShowEvent(mEventData, mFromUser); + } + + ShowEventData mEventData; + bool mFromUser; + }; + + struct SerializedHide final : public DeferredEvent + { + SerializedHide(DocAccessibleChild* aTarget, uint64_t aRootID, bool aFromUser) + : DeferredEvent(aTarget) + , mRootID(aRootID) + , mFromUser(aFromUser) + {} + + void Dispatch(DocAccessibleChild* aIPCDoc) override + { + Unused << aIPCDoc->SendHideEvent(mRootID, mFromUser); + } + + uint64_t mRootID; + bool mFromUser; + }; + + struct SerializedStateChange final : public DeferredEvent + { + SerializedStateChange(DocAccessibleChild* aTarget, uint64_t aID, + uint64_t aState, bool aEnabled) + : DeferredEvent(aTarget) + , mID(aID) + , mState(aState) + , mEnabled(aEnabled) + {} + + void Dispatch(DocAccessibleChild* aIPCDoc) override + { + Unused << aIPCDoc->SendStateChangeEvent(mID, mState, mEnabled); + } + + uint64_t mID; + uint64_t mState; + bool mEnabled; + }; + + struct SerializedCaretMove final : public DeferredEvent + { + SerializedCaretMove(DocAccessibleChild* aTarget, uint64_t aID, + int32_t aOffset) + : DeferredEvent(aTarget) + , mID(aID) + , mOffset(aOffset) + {} + + void Dispatch(DocAccessibleChild* aIPCDoc) override + { + Unused << aIPCDoc->SendCaretMoveEvent(mID, mOffset); + } + + uint64_t mID; + int32_t mOffset; + }; + + struct SerializedTextChange final : public DeferredEvent + { + SerializedTextChange(DocAccessibleChild* aTarget, uint64_t aID, + const nsString& aStr, int32_t aStart, uint32_t aLen, + bool aIsInsert, bool aFromUser) + : DeferredEvent(aTarget) + , mID(aID) + , mStr(aStr) + , mStart(aStart) + , mLen(aLen) + , mIsInsert(aIsInsert) + , mFromUser(aFromUser) + {} + + void Dispatch(DocAccessibleChild* aIPCDoc) override + { + Unused << aIPCDoc->SendTextChangeEvent(mID, mStr, mStart, mLen, mIsInsert, + mFromUser); + } + + uint64_t mID; + nsString mStr; + int32_t mStart; + uint32_t mLen; + bool mIsInsert; + bool mFromUser; + }; + + struct SerializedSelection final : public DeferredEvent + { + SerializedSelection(DocAccessibleChild* aTarget, uint64_t aID, + uint64_t aWidgetID, uint32_t aType) + : DeferredEvent(aTarget) + , mID(aID) + , mWidgetID(aWidgetID) + , mType(aType) + {} + + void Dispatch(DocAccessibleChild* aIPCDoc) override + { + Unused << aIPCDoc->SendSelectionEvent(mID, mWidgetID, mType); + } + + uint64_t mID; + uint64_t mWidgetID; + uint32_t mType; + }; + + struct SerializedRoleChanged final : public DeferredEvent + { + explicit SerializedRoleChanged(DocAccessibleChild* aTarget, uint32_t aRole) + : DeferredEvent(aTarget) + , mRole(aRole) + {} + + void Dispatch(DocAccessibleChild* aIPCDoc) override + { + Unused << aIPCDoc->SendRoleChangedEvent(mRole); + } + + uint32_t mRole; + }; + + struct SerializedEvent final : public DeferredEvent + { + SerializedEvent(DocAccessibleChild* aTarget, uint64_t aID, uint32_t aType) + : DeferredEvent(aTarget) + , mID(aID) + , mType(aType) + {} + + void Dispatch(DocAccessibleChild* aIPCDoc) override + { + Unused << aIPCDoc->SendEvent(mID, mType); + } + + uint64_t mID; + uint32_t mType; + }; + + struct SerializedChildDocConstructor final : public DeferredEvent + { + SerializedChildDocConstructor(DocAccessibleChild* aIPCDoc, + DocAccessibleChild* aParentIPCDoc, + uint64_t aUniqueID, uint32_t aMsaaID) + : DeferredEvent(aParentIPCDoc) + , mIPCDoc(aIPCDoc) + , mUniqueID(aUniqueID) + , mMsaaID(aMsaaID) + {} + + void Dispatch(DocAccessibleChild* aParentIPCDoc) override + { + auto tabChild = static_cast<dom::TabChild*>(aParentIPCDoc->Manager()); + MOZ_ASSERT(tabChild); + Unused << tabChild->SendPDocAccessibleConstructor(mIPCDoc, aParentIPCDoc, + mUniqueID, mMsaaID, + IAccessibleHolder()); + mIPCDoc->SetConstructedInParentProcess(); + } + + DocAccessibleChild* mIPCDoc; + uint64_t mUniqueID; + uint32_t mMsaaID; + }; + + friend struct SerializedChildDocConstructor; + + struct SerializedBindChildDoc final : public DeferredEvent + { + SerializedBindChildDoc(DocAccessibleChild* aParentDoc, + DocAccessibleChild* aChildDoc, uint64_t aNewParentID) + : DeferredEvent(aParentDoc) + , mChildDoc(aChildDoc) + , mNewParentID(aNewParentID) + {} + + void Dispatch(DocAccessibleChild* aParentIPCDoc) override + { + Unused << aParentIPCDoc->SendBindChildDoc(mChildDoc, mNewParentID); + } + + DocAccessibleChild* mChildDoc; + uint64_t mNewParentID; + }; + + struct SerializedShutdown final : public DeferredEvent + { + explicit SerializedShutdown(DocAccessibleChild* aTarget) + : DeferredEvent(aTarget) + { + } + + void Dispatch(DocAccessibleChild* aIPCDoc) override + { + aIPCDoc->Shutdown(); + } + }; + + bool mIsRemoteConstructed; + mscom::ProxyUniquePtr<IAccessible> mParentProxy; + nsTArray<UniquePtr<DeferredEvent>> mDeferredEvents; +}; + +} // namespace a11y +} // namespace mozilla + +#endif // mozilla_a11y_DocAccessibleChild_h diff --git a/accessible/ipc/win/PDocAccessible.ipdl b/accessible/ipc/win/PDocAccessible.ipdl new file mode 100644 index 000000000..3389abd23 --- /dev/null +++ b/accessible/ipc/win/PDocAccessible.ipdl @@ -0,0 +1,75 @@ +/* -*- 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/. */ + +include protocol PFileDescriptorSet; +include protocol PBrowser; + +using mozilla::a11y::IAccessibleHolder from "mozilla/a11y/IPCTypes.h"; +using mozilla::WindowsHandle from "ipc/IPCMessageUtils.h"; + +namespace mozilla { +namespace a11y { + +struct AccessibleData +{ + uint64_t ID; + int32_t MsaaID; + uint32_t Role; + uint32_t ChildrenCount; + uint32_t Interfaces; +}; + +struct ShowEventData +{ + uint64_t ID; + uint32_t Idx; + AccessibleData[] NewTree; +}; + +struct Attribute +{ + nsCString Name; + nsString Value; +}; + +sync protocol PDocAccessible +{ + manager PBrowser; + +parent: + async Shutdown(); + + /* + * Notify the parent process the document in the child process is firing an + * event. + */ + async Event(uint64_t aID, uint32_t type); + async ShowEvent(ShowEventData data, bool aFromUser); + async HideEvent(uint64_t aRootID, bool aFromUser); + async StateChangeEvent(uint64_t aID, uint64_t aState, bool aEnabled); + async CaretMoveEvent(uint64_t aID, int32_t aOffset); + async TextChangeEvent(uint64_t aID, nsString aStr, int32_t aStart, uint32_t aLen, + bool aIsInsert, bool aFromUser); + async SelectionEvent(uint64_t aID, uint64_t aWidgetID, uint32_t aType); + async RoleChangedEvent(uint32_t aRole); + + /* + * Tell the parent document to bind the existing document as a new child + * document. + */ + async BindChildDoc(PDocAccessible aChildDoc, uint64_t aID); + + sync GetWindowedPluginIAccessible(WindowsHandle aHwnd) + returns (IAccessibleHolder aPluginCOMProxy); + +child: + async ParentCOMProxy(IAccessibleHolder aParentCOMProxy); + + async __delete__(); +}; + +} +} diff --git a/accessible/ipc/win/PlatformChild.cpp b/accessible/ipc/win/PlatformChild.cpp new file mode 100644 index 000000000..01434a081 --- /dev/null +++ b/accessible/ipc/win/PlatformChild.cpp @@ -0,0 +1,62 @@ +/* -*- 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/. */ + +#include "mozilla/a11y/PlatformChild.h" +#include "mozilla/mscom/EnsureMTA.h" +#include "mozilla/mscom/InterceptorLog.h" + +#include "Accessible2.h" +#include "Accessible2_2.h" +#include "AccessibleHypertext2.h" +#include "AccessibleTableCell.h" + +#include "AccessibleHypertext2_i.c" + +namespace mozilla { +namespace a11y { + +/** + * Unfortunately the COM interceptor does not intrinsically handle array + * outparams. Instead we manually define the relevant metadata here, and + * register it in a call to mozilla::mscom::RegisterArrayData. + * @see mozilla::mscom::ArrayData + */ +static const mozilla::mscom::ArrayData sPlatformChildArrayData[] = { + {IID_IEnumVARIANT, 3, 1, VT_DISPATCH, IID_IDispatch, 2}, + {IID_IAccessible2, 30, 1, VT_UNKNOWN | VT_BYREF, IID_IAccessibleRelation, 2}, + {IID_IAccessibleRelation, 7, 1, VT_UNKNOWN | VT_BYREF, IID_IUnknown, 2}, + {IID_IAccessible2_2, 48, 2, VT_UNKNOWN | VT_BYREF, IID_IUnknown, 3, + mozilla::mscom::ArrayData::Flag::eAllocatedByServer}, + {IID_IAccessibleTableCell, 4, 0, VT_UNKNOWN | VT_BYREF, IID_IUnknown, 1, + mozilla::mscom::ArrayData::Flag::eAllocatedByServer}, + {IID_IAccessibleTableCell, 7, 0, VT_UNKNOWN | VT_BYREF, IID_IUnknown, 1, + mozilla::mscom::ArrayData::Flag::eAllocatedByServer}, + {IID_IAccessibleHypertext2, 25, 0, VT_UNKNOWN | VT_BYREF, IID_IUnknown, 1, + mozilla::mscom::ArrayData::Flag::eAllocatedByServer} +}; + +// Type libraries are thread-neutral, so we can register those from any +// apartment. OTOH, proxies must be registered from within the apartment where +// we intend to instantiate them. Therefore RegisterProxy() must be called +// via EnsureMTA. +PlatformChild::PlatformChild() + : mAccTypelib(mozilla::mscom::RegisterTypelib(L"oleacc.dll", + mozilla::mscom::RegistrationFlags::eUseSystemDirectory)) + , mMiscTypelib(mozilla::mscom::RegisterTypelib(L"Accessible.tlb")) +{ + mozilla::mscom::InterceptorLog::Init(); + mozilla::mscom::RegisterArrayData(sPlatformChildArrayData); + + UniquePtr<mozilla::mscom::RegisteredProxy> ia2Proxy; + mozilla::mscom::EnsureMTA([&ia2Proxy]() -> void { + ia2Proxy = Move(mozilla::mscom::RegisterProxy(L"ia2marshal.dll")); + }); + mIA2Proxy = Move(ia2Proxy); +} + +} // namespace a11y +} // namespace mozilla + diff --git a/accessible/ipc/win/PlatformChild.h b/accessible/ipc/win/PlatformChild.h new file mode 100644 index 000000000..49daf161d --- /dev/null +++ b/accessible/ipc/win/PlatformChild.h @@ -0,0 +1,35 @@ +/* -*- 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_PlatformChild_h +#define mozilla_a11y_PlatformChild_h + +#include "mozilla/mscom/Registration.h" + +namespace mozilla { +namespace a11y { + +class PlatformChild +{ +public: + PlatformChild(); + + PlatformChild(PlatformChild&) = delete; + PlatformChild(PlatformChild&&) = delete; + PlatformChild& operator=(PlatformChild&) = delete; + PlatformChild& operator=(PlatformChild&&) = delete; + +private: + UniquePtr<mozilla::mscom::RegisteredProxy> mIA2Proxy; + UniquePtr<mozilla::mscom::RegisteredProxy> mAccTypelib; + UniquePtr<mozilla::mscom::RegisteredProxy> mMiscTypelib; +}; + +} // namespace mozilla +} // namespace a11y + +#endif // mozilla_a11y_PlatformChild_h + diff --git a/accessible/ipc/win/ProxyAccessible.cpp b/accessible/ipc/win/ProxyAccessible.cpp new file mode 100644 index 000000000..dcdf20ef9 --- /dev/null +++ b/accessible/ipc/win/ProxyAccessible.cpp @@ -0,0 +1,599 @@ +/* -*- 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/. */ + +#include "Accessible2.h" +#include "ProxyAccessible.h" +#include "ia2AccessibleValue.h" +#include "mozilla/a11y/DocAccessibleParent.h" +#include "DocAccessible.h" +#include "mozilla/a11y/DocManager.h" +#include "mozilla/dom/Element.h" +#include "mozilla/dom/TabParent.h" +#include "mozilla/Unused.h" +#include "mozilla/a11y/Platform.h" +#include "RelationType.h" +#include "mozilla/a11y/Role.h" +#include "xpcAccessibleDocument.h" + +#include <comutil.h> + +static const VARIANT kChildIdSelf = {VT_I4}; + +namespace mozilla { +namespace a11y { + +bool +ProxyAccessible::GetCOMInterface(void** aOutAccessible) const +{ + if (!aOutAccessible) { + return false; + } + + if (!mCOMProxy) { + // See if we can lazily obtain a COM proxy + AccessibleWrap* wrap = WrapperFor(this); + bool isDefunct = false; + ProxyAccessible* thisPtr = const_cast<ProxyAccessible*>(this); + // NB: Don't pass CHILDID_SELF here, use the absolute MSAA ID. Otherwise + // GetIAccessibleFor will recurse into this function and we will just + // overflow the stack. + VARIANT realId = {VT_I4}; + realId.ulVal = wrap->GetExistingID(); + thisPtr->mCOMProxy = wrap->GetIAccessibleFor(realId, &isDefunct); + } + + RefPtr<IAccessible> addRefed = mCOMProxy; + addRefed.forget(aOutAccessible); + return !!mCOMProxy; +} + +/** + * Specializations of this template map an IAccessible type to its IID + */ +template<typename Interface> struct InterfaceIID {}; + +template<> +struct InterfaceIID<IAccessibleValue> +{ + static REFIID Value() { return IID_IAccessibleValue; } +}; + +template<> +struct InterfaceIID<IAccessibleText> +{ + static REFIID Value() { return IID_IAccessibleText; } +}; + +/** + * Get the COM proxy for this proxy accessible and QueryInterface it with the + * correct IID + */ +template<typename Interface> +static already_AddRefed<Interface> +QueryInterface(const ProxyAccessible* aProxy) +{ + RefPtr<IAccessible> acc; + if (!aProxy->GetCOMInterface((void**)getter_AddRefs(acc))) { + return nullptr; + } + + RefPtr<Interface> acc2; + if (FAILED(acc->QueryInterface(InterfaceIID<Interface>::Value(), + (void**)getter_AddRefs(acc2)))) { + return nullptr; + } + + return acc2.forget(); +} + +void +ProxyAccessible::Name(nsString& aName) const +{ + aName.Truncate(); + RefPtr<IAccessible> acc; + if (!GetCOMInterface((void**)getter_AddRefs(acc))) { + return; + } + + BSTR result; + HRESULT hr = acc->get_accName(kChildIdSelf, &result); + _bstr_t resultWrap(result, false); + if (FAILED(hr)) { + return; + } + aName = (wchar_t*)resultWrap; +} + +void +ProxyAccessible::Value(nsString& aValue) const +{ + aValue.Truncate(); + RefPtr<IAccessible> acc; + if (!GetCOMInterface((void**)getter_AddRefs(acc))) { + return; + } + + BSTR result; + HRESULT hr = acc->get_accValue(kChildIdSelf, &result); + _bstr_t resultWrap(result, false); + if (FAILED(hr)) { + return; + } + aValue = (wchar_t*)resultWrap; +} + +void +ProxyAccessible::Description(nsString& aDesc) const +{ + aDesc.Truncate(); + RefPtr<IAccessible> acc; + if (!GetCOMInterface((void**)getter_AddRefs(acc))) { + return; + } + + BSTR result; + HRESULT hr = acc->get_accDescription(kChildIdSelf, &result); + _bstr_t resultWrap(result, false); + if (FAILED(hr)) { + return; + } + aDesc = (wchar_t*)resultWrap; +} + +uint64_t +ProxyAccessible::State() const +{ + uint64_t state = 0; + RefPtr<IAccessible> acc; + if (!GetCOMInterface((void**)getter_AddRefs(acc))) { + return state; + } + + VARIANT varState; + HRESULT hr = acc->get_accState(kChildIdSelf, &varState); + if (FAILED(hr)) { + return state; + } + return uint64_t(varState.lVal); +} + +nsIntRect +ProxyAccessible::Bounds() +{ + nsIntRect rect; + + RefPtr<IAccessible> acc; + if (!GetCOMInterface((void**)getter_AddRefs(acc))) { + return rect; + } + + long left; + long top; + long width; + long height; + HRESULT hr = acc->accLocation(&left, &top, &width, &height, kChildIdSelf); + if (FAILED(hr)) { + return rect; + } + rect.x = left; + rect.y = top; + rect.width = width; + rect.height = height; + return rect; +} + +void +ProxyAccessible::Language(nsString& aLocale) +{ + aLocale.Truncate(); + + RefPtr<IAccessible> acc; + if (!GetCOMInterface((void**)getter_AddRefs(acc))) { + return; + } + + RefPtr<IAccessible2> acc2; + if (FAILED(acc->QueryInterface(IID_IAccessible2, (void**)getter_AddRefs(acc2)))) { + return; + } + + IA2Locale locale; + HRESULT hr = acc2->get_locale(&locale); + + _bstr_t langWrap(locale.language, false); + _bstr_t countryWrap(locale.country, false); + _bstr_t variantWrap(locale.variant, false); + + if (FAILED(hr)) { + return; + } + + // The remaining code should essentially be the inverse of the + // ia2Accessible::get_locale conversion to IA2Locale. + + if (!!variantWrap) { + aLocale = (wchar_t*)variantWrap; + return; + } + + if (!!langWrap) { + aLocale = (wchar_t*)langWrap; + if (!!countryWrap) { + aLocale += L"-"; + aLocale += (wchar_t*)countryWrap; + } + } +} + +static bool +IsEscapedChar(const wchar_t c) +{ + return c == L'\\' || c == L':' || c == ',' || c == '=' || c == ';'; +} + +static bool +ConvertBSTRAttributesToArray(const nsAString& aStr, + nsTArray<Attribute>* aAttrs) +{ + if (!aAttrs) { + return false; + } + + enum + { + eName = 0, + eValue = 1, + eNumStates + } state; + nsAutoString tokens[eNumStates]; + auto itr = aStr.BeginReading(), end = aStr.EndReading(); + + state = eName; + while (itr != end) { + switch (*itr) { + case L'\\': + // Skip the backslash so that we're looking at the escaped char + ++itr; + if (itr == end || !IsEscapedChar(*itr)) { + // Invalid state + return false; + } + break; + case L':': + if (state != eName) { + // Bad, should be looking at name + return false; + } + state = eValue; + ++itr; + continue; + case L';': + if (state != eValue) { + // Bad, should be looking at value + return false; + } + state = eName; + aAttrs->AppendElement(Attribute(NS_ConvertUTF16toUTF8(tokens[eName]), + tokens[eValue])); + tokens[eName].Truncate(); + tokens[eValue].Truncate(); + ++itr; + continue; + default: + break; + } + tokens[state] += *itr; + } + return true; +} + +void +ProxyAccessible::Attributes(nsTArray<Attribute>* aAttrs) const +{ + aAttrs->Clear(); + + RefPtr<IAccessible> acc; + if (!GetCOMInterface((void**)getter_AddRefs(acc))) { + return; + } + + RefPtr<IAccessible2> acc2; + if (FAILED(acc->QueryInterface(IID_IAccessible2, (void**)getter_AddRefs(acc2)))) { + return; + } + + BSTR attrs; + HRESULT hr = acc2->get_attributes(&attrs); + _bstr_t attrsWrap(attrs, false); + if (FAILED(hr)) { + return; + } + + ConvertBSTRAttributesToArray(nsDependentString((wchar_t*)attrs, + attrsWrap.length()), + aAttrs); +} + +double +ProxyAccessible::CurValue() +{ + RefPtr<IAccessibleValue> acc = QueryInterface<IAccessibleValue>(this); + if (!acc) { + return UnspecifiedNaN<double>(); + } + + VARIANT currentValue; + HRESULT hr = acc->get_currentValue(¤tValue); + if (FAILED(hr) || currentValue.vt != VT_R8) { + return UnspecifiedNaN<double>(); + } + + return currentValue.dblVal; +} + +bool +ProxyAccessible::SetCurValue(double aValue) +{ + RefPtr<IAccessibleValue> acc = QueryInterface<IAccessibleValue>(this); + if (!acc) { + return false; + } + + VARIANT currentValue; + VariantInit(¤tValue); + currentValue.vt = VT_R8; + currentValue.dblVal = aValue; + HRESULT hr = acc->setCurrentValue(currentValue); + return SUCCEEDED(hr); +} + +double +ProxyAccessible::MinValue() +{ + RefPtr<IAccessibleValue> acc = QueryInterface<IAccessibleValue>(this); + if (!acc) { + return UnspecifiedNaN<double>(); + } + + VARIANT minimumValue; + HRESULT hr = acc->get_minimumValue(&minimumValue); + if (FAILED(hr) || minimumValue.vt != VT_R8) { + return UnspecifiedNaN<double>(); + } + + return minimumValue.dblVal; +} + +double +ProxyAccessible::MaxValue() +{ + RefPtr<IAccessibleValue> acc = QueryInterface<IAccessibleValue>(this); + if (!acc) { + return UnspecifiedNaN<double>(); + } + + VARIANT maximumValue; + HRESULT hr = acc->get_maximumValue(&maximumValue); + if (FAILED(hr) || maximumValue.vt != VT_R8) { + return UnspecifiedNaN<double>(); + } + + return maximumValue.dblVal; +} + +static IA2TextBoundaryType +GetIA2TextBoundary(AccessibleTextBoundary aGeckoBoundaryType) +{ + switch (aGeckoBoundaryType) { + case nsIAccessibleText::BOUNDARY_CHAR: + return IA2_TEXT_BOUNDARY_CHAR; + case nsIAccessibleText::BOUNDARY_WORD_START: + return IA2_TEXT_BOUNDARY_WORD; + case nsIAccessibleText::BOUNDARY_LINE_START: + return IA2_TEXT_BOUNDARY_LINE; + default: + MOZ_RELEASE_ASSERT(false); + } +} + +bool +ProxyAccessible::TextSubstring(int32_t aStartOffset, int32_t aEndOffset, + nsString& aText) const +{ + RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this); + if (!acc) { + return false; + } + + BSTR result; + HRESULT hr = acc->get_text(static_cast<long>(aStartOffset), + static_cast<long>(aEndOffset), &result); + if (FAILED(hr)) { + return false; + } + + _bstr_t resultWrap(result, false); + aText = (wchar_t*)result; + + return true; +} + +void +ProxyAccessible::GetTextBeforeOffset(int32_t aOffset, + AccessibleTextBoundary aBoundaryType, + nsString& aText, int32_t* aStartOffset, + int32_t* aEndOffset) +{ + RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this); + if (!acc) { + return; + } + + BSTR result; + long start, end; + HRESULT hr = acc->get_textBeforeOffset(aOffset, + GetIA2TextBoundary(aBoundaryType), + &start, &end, &result); + if (FAILED(hr)) { + return; + } + + _bstr_t resultWrap(result, false); + *aStartOffset = start; + *aEndOffset = end; + aText = (wchar_t*)result; +} + +void +ProxyAccessible::GetTextAfterOffset(int32_t aOffset, + AccessibleTextBoundary aBoundaryType, + nsString& aText, int32_t* aStartOffset, + int32_t* aEndOffset) +{ + RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this); + if (!acc) { + return; + } + + BSTR result; + long start, end; + HRESULT hr = acc->get_textAfterOffset(aOffset, + GetIA2TextBoundary(aBoundaryType), + &start, &end, &result); + if (FAILED(hr)) { + return; + } + + _bstr_t resultWrap(result, false); + aText = (wchar_t*)result; + *aStartOffset = start; + *aEndOffset = end; +} + +void +ProxyAccessible::GetTextAtOffset(int32_t aOffset, + AccessibleTextBoundary aBoundaryType, + nsString& aText, int32_t* aStartOffset, + int32_t* aEndOffset) +{ + RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this); + if (!acc) { + return; + } + + BSTR result; + long start, end; + HRESULT hr = acc->get_textAtOffset(aOffset, GetIA2TextBoundary(aBoundaryType), + &start, &end, &result); + if (FAILED(hr)) { + return; + } + + _bstr_t resultWrap(result, false); + aText = (wchar_t*)result; + *aStartOffset = start; + *aEndOffset = end; +} + +bool +ProxyAccessible::AddToSelection(int32_t aStartOffset, int32_t aEndOffset) +{ + RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this); + if (!acc) { + return false; + } + + return SUCCEEDED(acc->addSelection(static_cast<long>(aStartOffset), + static_cast<long>(aEndOffset))); +} + +bool +ProxyAccessible::RemoveFromSelection(int32_t aSelectionNum) +{ + RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this); + if (!acc) { + return false; + } + + return SUCCEEDED(acc->removeSelection(static_cast<long>(aSelectionNum))); +} + +int32_t +ProxyAccessible::CaretOffset() +{ + RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this); + if (!acc) { + return -1; + } + + long offset; + HRESULT hr = acc->get_caretOffset(&offset); + if (FAILED(hr)) { + return -1; + } + + return static_cast<int32_t>(offset); +} + +void +ProxyAccessible::SetCaretOffset(int32_t aOffset) +{ + RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this); + if (!acc) { + return; + } + + acc->setCaretOffset(static_cast<long>(aOffset)); +} + +/** + * aScrollType should be one of the nsIAccessiblescrollType constants. + */ +void +ProxyAccessible::ScrollSubstringTo(int32_t aStartOffset, int32_t aEndOffset, + uint32_t aScrollType) +{ + RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this); + if (!acc) { + return; + } + + acc->scrollSubstringTo(static_cast<long>(aStartOffset), + static_cast<long>(aEndOffset), + static_cast<IA2ScrollType>(aScrollType)); +} + +/** + * aCoordinateType is one of the nsIAccessibleCoordinateType constants. + */ +void +ProxyAccessible::ScrollSubstringToPoint(int32_t aStartOffset, int32_t aEndOffset, + uint32_t aCoordinateType, int32_t aX, + int32_t aY) +{ + RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this); + if (!acc) { + return; + } + + IA2CoordinateType coordType; + if (aCoordinateType == nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE) { + coordType = IA2_COORDTYPE_SCREEN_RELATIVE; + } else if (aCoordinateType == nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE) { + coordType = IA2_COORDTYPE_PARENT_RELATIVE; + } else { + MOZ_RELEASE_ASSERT(false, "unsupported coord type"); + } + + acc->scrollSubstringToPoint(static_cast<long>(aStartOffset), + static_cast<long>(aEndOffset), + coordType, + static_cast<long>(aX), + static_cast<long>(aY)); +} + +} // namespace a11y +} // namespace mozilla diff --git a/accessible/ipc/win/ProxyAccessible.h b/accessible/ipc/win/ProxyAccessible.h new file mode 100644 index 000000000..c8e5a43b1 --- /dev/null +++ b/accessible/ipc/win/ProxyAccessible.h @@ -0,0 +1,58 @@ +/* -*- 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_ProxyAccessible_h +#define mozilla_a11y_ProxyAccessible_h + +#include "Accessible.h" +#include "mozilla/a11y/ProxyAccessibleBase.h" +#include "mozilla/a11y/Role.h" +#include "nsIAccessibleText.h" +#include "nsIAccessibleTypes.h" +#include "nsString.h" +#include "nsTArray.h" +#include "nsRect.h" + +#include <oleacc.h> + +namespace mozilla { +namespace a11y { + +class ProxyAccessible : public ProxyAccessibleBase<ProxyAccessible> +{ +public: + ProxyAccessible(uint64_t aID, ProxyAccessible* aParent, + DocAccessibleParent* aDoc, role aRole, uint32_t aInterfaces) + : ProxyAccessibleBase(aID, aParent, aDoc, aRole, aInterfaces) + { + MOZ_COUNT_CTOR(ProxyAccessible); + } + + ~ProxyAccessible() + { + MOZ_COUNT_DTOR(ProxyAccessible); + } + +#include "mozilla/a11y/ProxyAccessibleShared.h" + + bool GetCOMInterface(void** aOutAccessible) const; + +protected: + explicit ProxyAccessible(DocAccessibleParent* aThisAsDoc) + : ProxyAccessibleBase(aThisAsDoc) + { MOZ_COUNT_CTOR(ProxyAccessible); } + + void SetCOMInterface(const RefPtr<IAccessible>& aIAccessible) + { mCOMProxy = aIAccessible; } + +private: + RefPtr<IAccessible> mCOMProxy; +}; + +} +} + +#endif diff --git a/accessible/ipc/win/moz.build b/accessible/ipc/win/moz.build new file mode 100644 index 000000000..4bbcec417 --- /dev/null +++ b/accessible/ipc/win/moz.build @@ -0,0 +1,39 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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 CONFIG['COMPILE_ENVIRONMENT']: + DIRS += ['typelib'] + +# With --disable-accessibility, we need to compile PDocAccessible.ipdl (which +# also depends on COMPtrTypes.h), but not the C++. +IPDL_SOURCES += ['PDocAccessible.ipdl'] +EXPORTS.mozilla.a11y += ['COMPtrTypes.h'] + +if CONFIG['ACCESSIBILITY']: + EXPORTS.mozilla.a11y += [ + 'DocAccessibleChild.h', + 'PlatformChild.h', + 'ProxyAccessible.h' + ] + + SOURCES += [ + 'COMPtrTypes.cpp', + 'DocAccessibleChild.cpp', + 'PlatformChild.cpp', + 'ProxyAccessible.cpp', + ] + + LOCAL_INCLUDES += [ + '/accessible/base', + '/accessible/generic', + '/accessible/windows/ia2', + '/accessible/windows/msaa', + '/accessible/xpcom', + ] + +include('/ipc/chromium/chromium-config.mozbuild') + +FINAL_LIBRARY = 'xul' diff --git a/accessible/ipc/win/typelib/Accessible.idl b/accessible/ipc/win/typelib/Accessible.idl new file mode 100644 index 000000000..82ddcf506 --- /dev/null +++ b/accessible/ipc/win/typelib/Accessible.idl @@ -0,0 +1,16 @@ +/* -*- 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/. */ + +import "oaidl.idl"; +import "servprov.idl"; + +[uuid(b4d37cda-0dac-45e6-b613-158a5eb94293)] +library Accessible +{ + interface IEnumVARIANT; + interface IServiceProvider; +}; + diff --git a/accessible/ipc/win/typelib/Makefile.in b/accessible/ipc/win/typelib/Makefile.in new file mode 100644 index 000000000..78e0cea29 --- /dev/null +++ b/accessible/ipc/win/typelib/Makefile.in @@ -0,0 +1,31 @@ +# 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/. + +GARBAGE += $(MIDL_GENERATED_FILES) done_gen dlldata.c + +MIDL_GENERATED_FILES = \ + Accessible.h \ + Accessible_i.c \ + Accessible_p.c \ + Accessible.tlb \ + $(NULL) + +$(MIDL_GENERATED_FILES): done_gen + +done_gen: Accessible.idl + $(MIDL) $(MIDL_FLAGS) -Oicf $(srcdir)/Accessible.idl + touch $@ + +export:: done_gen + +midl_exports := \ + Accessible.tlb \ + $(NULL) + +INSTALL_TARGETS += midl_exports +midl_exports_FILES := $(midl_exports) +midl_exports_DEST = $(DIST)/bin +midl_exports_TARGET := export + +include $(topsrcdir)/config/rules.mk diff --git a/accessible/ipc/win/typelib/moz.build b/accessible/ipc/win/typelib/moz.build new file mode 100644 index 000000000..3bc45a136 --- /dev/null +++ b/accessible/ipc/win/typelib/moz.build @@ -0,0 +1,13 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +FINAL_TARGET_FILES += [ + '!Accessible.tlb', +] + +GENERATED_FILES += [ + 'Accessible.tlb', +] |