diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index 42362fe8395..76daa6fd840 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -48,11 +48,16 @@ include "mozilla/TabTypes.h"; include "TabMessageUtils.h"; include "gfxMatrix.h"; include "mozilla/net/NeckoMessageUtils.h"; +include "mozilla/widget/nsGUIEventIPC.h"; using IPC::URI; using MagicWindowHandle; using RemoteDOMEvent; using gfxMatrix; +using nsCompositionEvent; +using nsTextEvent; +using nsQueryContentEvent; +using nsSelectionEvent; namespace mozilla { namespace dom { @@ -105,6 +110,8 @@ parent: sync SyncMessage(nsString aMessage, nsString aJSON) returns (nsString[] retval); + QueryContentResult(nsQueryContentEvent event); + PGeolocationRequest(URI uri); PContentDialog(PRUint32 aType, nsCString aName, nsCString aFeatures, @@ -147,6 +154,14 @@ child: PRInt32 aModifiers, bool aPreventDefault); + CompositionEvent(nsCompositionEvent event); + + TextEvent(nsTextEvent event); + + QueryContentEvent(nsQueryContentEvent event); + + SelectionEvent(nsSelectionEvent event); + /** * Activate event forwarding from client to parent. */ diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index 8794361df93..55caa675d92 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -80,6 +80,8 @@ #include "nsIDOMDocument.h" #include "nsIScriptGlobalObject.h" #include "nsWeakReference.h" +#include "nsIFrame.h" +#include "nsIView.h" #include "nsISecureBrowserUI.h" #include "nsISSLStatusProvider.h" #include "nsSerializationHelper.h" @@ -720,15 +722,76 @@ TabChild::RecvKeyEvent(const nsString& aType, return true; } +bool +TabChild::RecvCompositionEvent(const nsCompositionEvent& event) +{ + nsCompositionEvent localEvent(event); + DispatchWidgetEvent(localEvent); + return true; +} + +bool +TabChild::RecvTextEvent(const nsTextEvent& event) +{ + nsTextEvent localEvent(event); + DispatchWidgetEvent(localEvent); + return true; +} + +bool +TabChild::RecvQueryContentEvent(const nsQueryContentEvent& event) +{ + nsQueryContentEvent localEvent(event); + DispatchWidgetEvent(localEvent); + // Send result back even if query failed + SendQueryContentResult(localEvent); + return true; +} + +bool +TabChild::RecvSelectionEvent(const nsSelectionEvent& event) +{ + nsSelectionEvent localEvent(event); + DispatchWidgetEvent(localEvent); + return true; +} + +bool +TabChild::DispatchWidgetEvent(nsGUIEvent& event) +{ + nsCOMPtr window = do_GetInterface(mWebNav); + NS_ENSURE_TRUE(window, false); + + nsIDocShell *docShell = window->GetDocShell(); + NS_ENSURE_TRUE(docShell, false); + + nsCOMPtr presShell; + docShell->GetPresShell(getter_AddRefs(presShell)); + NS_ENSURE_TRUE(presShell, false); + + nsIFrame *frame = presShell->GetRootFrame(); + NS_ENSURE_TRUE(frame, false); + + nsIView *view = frame->GetView(); + NS_ENSURE_TRUE(view, false); + + nsCOMPtr widget = view->GetNearestWidget(nsnull); + NS_ENSURE_TRUE(widget, false); + + nsEventStatus status; + event.widget = widget; + NS_ENSURE_SUCCESS(widget->DispatchEvent(&event, status), false); + return true; +} + mozilla::ipc::PDocumentRendererChild* -TabChild::AllocPDocumentRenderer( - const PRInt32& x, - const PRInt32& y, - const PRInt32& w, - const PRInt32& h, - const nsString& bgcolor, - const PRUint32& flags, - const bool& flush) +TabChild::AllocPDocumentRenderer(const PRInt32& x, + const PRInt32& y, + const PRInt32& w, + const PRInt32& h, + const nsString& bgcolor, + const PRUint32& flags, + const bool& flush) { return new mozilla::ipc::DocumentRendererChild(); } diff --git a/dom/ipc/TabChild.h b/dom/ipc/TabChild.h index 07a0edcbc9a..0283d7f2458 100644 --- a/dom/ipc/TabChild.h +++ b/dom/ipc/TabChild.h @@ -191,6 +191,10 @@ public: const PRInt32& aCharCode, const PRInt32& aModifiers, const bool& aPreventDefault); + virtual bool RecvCompositionEvent(const nsCompositionEvent& event); + virtual bool RecvTextEvent(const nsTextEvent& event); + virtual bool RecvQueryContentEvent(const nsQueryContentEvent& event); + virtual bool RecvSelectionEvent(const nsSelectionEvent& event); virtual bool RecvActivateFrameEvent(const nsString& aType, const bool& capture); virtual bool RecvLoadRemoteScript(const nsString& aURL); virtual bool RecvAsyncMessage(const nsString& aMessage, @@ -285,6 +289,8 @@ protected: NS_OVERRIDE virtual bool RecvDestroy(); + bool DispatchWidgetEvent(nsGUIEvent& event); + private: void ActorDestroy(ActorDestroyReason why); diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index 4f0d720a294..1a043626018 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -567,6 +567,12 @@ TabParent::RecvAsyncMessage(const nsString& aMessage, return ReceiveMessage(aMessage, PR_FALSE, aJSON, nsnull); } +bool +TabParent::RecvQueryContentResult(const nsQueryContentEvent& event) +{ + return true; +} + bool TabParent::ReceiveMessage(const nsString& aMessage, PRBool aSync, diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index 817924f1a31..d6dabb1c648 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -132,6 +132,7 @@ public: nsTArray* aJSONRetVal); virtual bool RecvAsyncMessage(const nsString& aMessage, const nsString& aJSON); + virtual bool RecvQueryContentResult(const nsQueryContentEvent& event); virtual PContentDialogParent* AllocPContentDialog(const PRUint32& aType, const nsCString& aName, const nsCString& aFeatures, diff --git a/widget/public/Makefile.in b/widget/public/Makefile.in index c50be2c1c12..120a1019488 100644 --- a/widget/public/Makefile.in +++ b/widget/public/Makefile.in @@ -46,6 +46,12 @@ MODULE = widget XPIDL_MODULE = widget GRE_MODULE = 1 +EXPORTS_NAMESPACES = mozilla/widget + +EXPORTS_mozilla/widget = \ + nsGUIEventIPC.h \ + $(NULL) + EXPORTS = \ nsIWidget.h \ nsGUIEvent.h \ diff --git a/widget/public/nsGUIEvent.h b/widget/public/nsGUIEvent.h index 76c62b3591c..469038965be 100644 --- a/widget/public/nsGUIEvent.h +++ b/widget/public/nsGUIEvent.h @@ -60,6 +60,15 @@ #include "nsITransferable.h" #include "nsIVariant.h" +#ifdef MOZ_IPC +namespace mozilla { +namespace dom { + class PBrowserParent; + class PBrowserChild; +} +} +#endif // MOZ_IPC + #ifdef ACCESSIBILITY class nsAccessible; #endif @@ -509,6 +518,12 @@ protected: MOZ_COUNT_CTOR(nsEvent); } +#ifdef MOZ_IPC + nsEvent() + { + } +#endif // MOZ_IPC + public: nsEvent(PRBool isTrusted, PRUint32 msg) : eventStructType(NS_EVENT), @@ -560,6 +575,13 @@ protected: { } +#ifdef MOZ_IPC + nsGUIEvent() + : pluginEvent(nsnull) + { + } +#endif // MOZ_IPC + public: nsGUIEvent(PRBool isTrusted, PRUint32 msg, nsIWidget *w) : nsEvent(isTrusted, msg, NS_GUI_EVENT), @@ -724,6 +746,12 @@ protected: { } +#ifdef MOZ_IPC + nsInputEvent() + { + } +#endif // MOZ_IPC + public: nsInputEvent(PRBool isTrusted, PRUint32 msg, nsIWidget *w) : nsGUIEvent(isTrusted, msg, w, NS_INPUT_EVENT), @@ -1020,6 +1048,35 @@ typedef nsTextRange* nsTextRangeArray; class nsTextEvent : public nsInputEvent { +#ifdef MOZ_IPC +private: + friend class mozilla::dom::PBrowserParent; + friend class mozilla::dom::PBrowserChild; + + nsTextEvent() + : mOwnRangeArray(PR_FALSE), rangeArray(nsnull) + { + } + + PRPackedBool mOwnRangeArray; + +public: + ~nsTextEvent() + { + if (mOwnRangeArray && rangeArray) + delete [] rangeArray; + } + + nsTextRangeArray AllocRangeArray(PRUint32 aCount) + { + NS_ASSERTION(!rangeArray, "rangeArray already allocated"); + mOwnRangeArray = PR_TRUE; + rangeCount = aCount; + rangeArray = new nsTextRange[aCount]; + return rangeArray; + } +#endif // MOZ_IPC + public: nsTextEvent(PRBool isTrusted, PRUint32 msg, nsIWidget *w) : nsInputEvent(isTrusted, msg, w, NS_TEXT_EVENT), @@ -1038,6 +1095,16 @@ public: class nsCompositionEvent : public nsInputEvent { +#ifdef MOZ_IPC +private: + friend class mozilla::dom::PBrowserParent; + friend class mozilla::dom::PBrowserChild; + + nsCompositionEvent() + { + } +#endif // MOZ_IPC + public: nsCompositionEvent(PRBool isTrusted, PRUint32 msg, nsIWidget *w) : nsInputEvent(isTrusted, msg, w, NS_COMPOSITION_EVENT) @@ -1152,6 +1219,18 @@ public: class nsQueryContentEvent : public nsGUIEvent { +#ifdef MOZ_IPC +private: + friend class mozilla::dom::PBrowserParent; + friend class mozilla::dom::PBrowserChild; + + nsQueryContentEvent() + { + mReply.mContentsRoot = nsnull; + mReply.mFocusedWidget = nsnull; + } +#endif // MOZ_IPC + public: nsQueryContentEvent(PRBool aIsTrusted, PRUint32 aMsg, nsIWidget *aWidget) : nsGUIEvent(aIsTrusted, aMsg, aWidget, NS_QUERY_CONTENT_EVENT), @@ -1219,6 +1298,16 @@ public: class nsSelectionEvent : public nsGUIEvent { +#ifdef MOZ_IPC +private: + friend class mozilla::dom::PBrowserParent; + friend class mozilla::dom::PBrowserChild; + + nsSelectionEvent() + { + } +#endif // MOZ_IPC + public: nsSelectionEvent(PRBool aIsTrusted, PRUint32 aMsg, nsIWidget *aWidget) : nsGUIEvent(aIsTrusted, aMsg, aWidget, NS_SELECTION_EVENT), diff --git a/widget/public/nsGUIEventIPC.h b/widget/public/nsGUIEventIPC.h new file mode 100644 index 00000000000..eac5ef0fc9a --- /dev/null +++ b/widget/public/nsGUIEventIPC.h @@ -0,0 +1,272 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * The Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsGUIEventIPC_h__ +#define nsGUIEventIPC_h__ + +#include "IPC/IPCMessageUtils.h" +#include "nsGUIEvent.h" + +namespace IPC +{ + +template<> +struct ParamTraits +{ + typedef nsEvent paramType; + + static void Write(Message* aMsg, const paramType& aParam) + { + WriteParam(aMsg, aParam.eventStructType); + WriteParam(aMsg, aParam.message); + WriteParam(aMsg, aParam.refPoint); + WriteParam(aMsg, aParam.time); + WriteParam(aMsg, aParam.flags); + } + + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) + { + return ReadParam(aMsg, aIter, &aResult->eventStructType) && + ReadParam(aMsg, aIter, &aResult->message) && + ReadParam(aMsg, aIter, &aResult->refPoint) && + ReadParam(aMsg, aIter, &aResult->time) && + ReadParam(aMsg, aIter, &aResult->flags); + } +}; + +template<> +struct ParamTraits +{ + typedef nsGUIEvent paramType; + + static void Write(Message* aMsg, const paramType& aParam) + { + WriteParam(aMsg, static_cast(aParam)); + } + + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) + { + return ReadParam(aMsg, aIter, static_cast(aResult)); + } +}; + +template<> +struct ParamTraits +{ + typedef nsInputEvent paramType; + + static void Write(Message* aMsg, const paramType& aParam) + { + WriteParam(aMsg, static_cast(aParam)); + WriteParam(aMsg, aParam.isShift); + WriteParam(aMsg, aParam.isControl); + WriteParam(aMsg, aParam.isAlt); + WriteParam(aMsg, aParam.isMeta); + } + + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) + { + return ReadParam(aMsg, aIter, static_cast(aResult)) && + ReadParam(aMsg, aIter, &aResult->isShift) && + ReadParam(aMsg, aIter, &aResult->isControl) && + ReadParam(aMsg, aIter, &aResult->isAlt) && + ReadParam(aMsg, aIter, &aResult->isMeta); + } +}; + +template<> +struct ParamTraits +{ + typedef nsTextRangeStyle paramType; + + static void Write(Message* aMsg, const paramType& aParam) + { + WriteParam(aMsg, aParam.mDefinedStyles); + WriteParam(aMsg, aParam.mLineStyle); + WriteParam(aMsg, aParam.mIsBoldLine); + WriteParam(aMsg, aParam.mForegroundColor); + WriteParam(aMsg, aParam.mBackgroundColor); + WriteParam(aMsg, aParam.mUnderlineColor); + } + + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) + { + return ReadParam(aMsg, aIter, &aResult->mDefinedStyles) && + ReadParam(aMsg, aIter, &aResult->mLineStyle) && + ReadParam(aMsg, aIter, &aResult->mIsBoldLine) && + ReadParam(aMsg, aIter, &aResult->mForegroundColor) && + ReadParam(aMsg, aIter, &aResult->mBackgroundColor) && + ReadParam(aMsg, aIter, &aResult->mUnderlineColor); + } +}; + +template<> +struct ParamTraits +{ + typedef nsTextRange paramType; + + static void Write(Message* aMsg, const paramType& aParam) + { + WriteParam(aMsg, aParam.mStartOffset); + WriteParam(aMsg, aParam.mEndOffset); + WriteParam(aMsg, aParam.mRangeType); + WriteParam(aMsg, aParam.mRangeStyle); + } + + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) + { + return ReadParam(aMsg, aIter, &aResult->mStartOffset) && + ReadParam(aMsg, aIter, &aResult->mEndOffset) && + ReadParam(aMsg, aIter, &aResult->mRangeType) && + ReadParam(aMsg, aIter, &aResult->mRangeStyle); + } +}; + +template<> +struct ParamTraits +{ + typedef nsTextEvent paramType; + + static void Write(Message* aMsg, const paramType& aParam) + { + WriteParam(aMsg, static_cast(aParam)); + WriteParam(aMsg, aParam.theText); + WriteParam(aMsg, aParam.isChar); + WriteParam(aMsg, aParam.rangeCount); + for (PRUint32 index = 0; index < aParam.rangeCount; index++) + WriteParam(aMsg, aParam.rangeArray[index]); + } + + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) + { + if (!ReadParam(aMsg, aIter, static_cast(aResult)) || + !ReadParam(aMsg, aIter, &aResult->theText) || + !ReadParam(aMsg, aIter, &aResult->isChar) || + !ReadParam(aMsg, aIter, &aResult->rangeCount)) + return false; + + if (!aResult->rangeCount) + return true; + + if (!aResult->AllocRangeArray(aResult->rangeCount)) + return false; + + for (PRUint32 index = 0; index < aResult->rangeCount; index++) + if (!ReadParam(aMsg, aIter, &aResult->rangeArray[index])) + return false; + return true; + } +}; + +template<> +struct ParamTraits +{ + typedef nsCompositionEvent paramType; + + static void Write(Message* aMsg, const paramType& aParam) + { + WriteParam(aMsg, static_cast(aParam)); + } + + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) + { + return ReadParam(aMsg, aIter, static_cast(aResult)); + } +}; + +template<> +struct ParamTraits +{ + typedef nsQueryContentEvent paramType; + + static void Write(Message* aMsg, const paramType& aParam) + { + WriteParam(aMsg, static_cast(aParam)); + WriteParam(aMsg, aParam.mSucceeded); + WriteParam(aMsg, aParam.mInput.mOffset); + WriteParam(aMsg, aParam.mInput.mLength); + WriteParam(aMsg, aParam.mReply.mOffset); + WriteParam(aMsg, aParam.mReply.mString); + WriteParam(aMsg, aParam.mReply.mRect); + WriteParam(aMsg, aParam.mReply.mReversed); + WriteParam(aMsg, aParam.mReply.mHasSelection); + } + + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) + { + return ReadParam(aMsg, aIter, static_cast(aResult)) && + ReadParam(aMsg, aIter, &aResult->mSucceeded) && + ReadParam(aMsg, aIter, &aResult->mInput.mOffset) && + ReadParam(aMsg, aIter, &aResult->mInput.mLength) && + ReadParam(aMsg, aIter, &aResult->mReply.mOffset) && + ReadParam(aMsg, aIter, &aResult->mReply.mString) && + ReadParam(aMsg, aIter, &aResult->mReply.mRect) && + ReadParam(aMsg, aIter, &aResult->mReply.mReversed) && + ReadParam(aMsg, aIter, &aResult->mReply.mHasSelection); + } +}; + +template<> +struct ParamTraits +{ + typedef nsSelectionEvent paramType; + + static void Write(Message* aMsg, const paramType& aParam) + { + WriteParam(aMsg, static_cast(aParam)); + WriteParam(aMsg, aParam.mOffset); + WriteParam(aMsg, aParam.mLength); + WriteParam(aMsg, aParam.mReversed); + WriteParam(aMsg, aParam.mExpandToClusterBoundary); + WriteParam(aMsg, aParam.mSucceeded); + } + + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) + { + return ReadParam(aMsg, aIter, static_cast(aResult)) && + ReadParam(aMsg, aIter, &aResult->mOffset) && + ReadParam(aMsg, aIter, &aResult->mLength) && + ReadParam(aMsg, aIter, &aResult->mReversed) && + ReadParam(aMsg, aIter, &aResult->mExpandToClusterBoundary) && + ReadParam(aMsg, aIter, &aResult->mSucceeded); + } +}; + +} // namespace IPC + +#endif // nsGUIEventIPC_h__ +