/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8; -*- */ /* vim: set sw=4 ts=8 et tw=80 : */ /* ***** 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 Content App. * * The Initial Developer of the Original Code is * The Mozilla Foundation. * Portions created by the Initial Developer are Copyright (C) 2009 * 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 ***** */ #include "TabChild.h" #include "nsIWebBrowser.h" #include "nsEmbedCID.h" #include "nsComponentManagerUtils.h" #include "nsIBaseWindow.h" #include "nsIDOMWindow.h" #include "nsIDocShellTreeItem.h" #include "nsThreadUtils.h" #include "nsIInterfaceRequestorUtils.h" #include "mozilla/ipc/DocumentRendererChild.h" #include "nsIInterfaceRequestorUtils.h" #include "nsPIDOMWindow.h" #include "nsIDOMWindowUtils.h" #include "nsISupportsImpl.h" #include "nsIWebBrowserFocus.h" #include "nsIDOMEvent.h" #include "nsIPrivateDOMEvent.h" #ifdef MOZ_WIDGET_GTK2 #include #include #endif using namespace mozilla::dom; NS_IMPL_ISUPPORTS1(ContentListener, nsIDOMEventListener) NS_IMETHODIMP ContentListener::HandleEvent(nsIDOMEvent* aEvent) { RemoteDOMEvent remoteEvent; remoteEvent.mEvent = do_QueryInterface(aEvent); NS_ENSURE_STATE(remoteEvent.mEvent); mTabChild->SendsendEvent(remoteEvent); return NS_OK; } TabChild::TabChild() { printf("creating %d!\n", NS_IsMainThread()); } nsresult TabChild::Init() { #ifdef MOZ_WIDGET_GTK2 gtk_init(NULL, NULL); #endif nsCOMPtr webBrowser = do_CreateInstance(NS_WEBBROWSER_CONTRACTID); if (!webBrowser) { NS_ERROR("Couldn't create a nsWebBrowser?"); return NS_ERROR_FAILURE; } webBrowser->SetContainerWindow(this); mWebNav = do_QueryInterface(webBrowser); NS_ASSERTION(mWebNav, "nsWebBrowser doesn't implement nsIWebNavigation?"); nsCOMPtr docShellItem(do_QueryInterface(mWebNav)); docShellItem->SetItemType(nsIDocShellTreeItem::typeContentWrapper); return NS_OK; } NS_IMPL_ISUPPORTS7(TabChild, nsIWebBrowserChrome, nsIWebBrowserChrome2, nsIEmbeddingSiteWindow, nsIEmbeddingSiteWindow2, nsIWebBrowserChromeFocus, nsIInterfaceRequestor, nsIWindowProvider) NS_IMETHODIMP TabChild::SetStatus(PRUint32 aStatusType, const PRUnichar* aStatus) { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP TabChild::GetWebBrowser(nsIWebBrowser** aWebBrowser) { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP TabChild::SetWebBrowser(nsIWebBrowser* aWebBrowser) { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP TabChild::GetChromeFlags(PRUint32* aChromeFlags) { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP TabChild::SetChromeFlags(PRUint32 aChromeFlags) { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP TabChild::DestroyBrowserWindow() { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP TabChild::SizeBrowserTo(PRInt32 aCX, PRInt32 aCY) { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP TabChild::ShowAsModal() { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP TabChild::IsWindowModal(PRBool* aRetVal) { *aRetVal = PR_FALSE; return NS_OK; } NS_IMETHODIMP TabChild::ExitModalEventLoop(nsresult aStatus) { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP TabChild::SetStatusWithContext(PRUint32 aStatusType, const nsAString& aStatusText, nsISupports* aStatusContext) { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP TabChild::SetDimensions(PRUint32 aFlags, PRInt32 aX, PRInt32 aY, PRInt32 aCx, PRInt32 aCy) { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP TabChild::GetDimensions(PRUint32 aFlags, PRInt32* aX, PRInt32* aY, PRInt32* aCx, PRInt32* aCy) { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP TabChild::SetFocus() { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP TabChild::GetVisibility(PRBool* aVisibility) { *aVisibility = PR_TRUE; return NS_OK; } NS_IMETHODIMP TabChild::SetVisibility(PRBool aVisibility) { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP TabChild::GetTitle(PRUnichar** aTitle) { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP TabChild::SetTitle(const PRUnichar* aTitle) { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP TabChild::GetSiteWindow(void** aSiteWindow) { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP TabChild::Blur() { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP TabChild::FocusNextElement() { SendmoveFocus(PR_TRUE); return NS_OK; } NS_IMETHODIMP TabChild::FocusPrevElement() { SendmoveFocus(PR_FALSE); return NS_OK; } NS_IMETHODIMP TabChild::GetInterface(const nsIID & aIID, void **aSink) { // XXXbz should we restrict the set of interfaces we hand out here? // See bug 537429 return QueryInterface(aIID, aSink); } NS_IMETHODIMP TabChild::ProvideWindow(nsIDOMWindow* aParent, PRUint32 aChromeFlags, PRBool aPositionSpecified, PRBool aSizeSpecified, nsIURI* aURI, const nsAString& aName, const nsACString& aFeatures, PRBool* aWindowIsNew, nsIDOMWindow** aReturn) { *aReturn = nsnull; PIFrameEmbeddingChild* newChild; if (!CallcreateWindow(&newChild)) { return NS_ERROR_NOT_AVAILABLE; } nsCOMPtr win = do_GetInterface(static_cast(newChild)->mWebNav); win.forget(aReturn); return NS_OK; } bool TabChild::RecvcreateWidget(const MagicWindowHandle& parentWidget) { nsCOMPtr baseWindow = do_QueryInterface(mWebNav); if (!baseWindow) { NS_ERROR("mWebNav doesn't QI to nsIBaseWindow"); return true; } #ifdef MOZ_WIDGET_GTK2 GtkWidget* win = gtk_plug_new((GdkNativeWindow)parentWidget); gtk_widget_show(win); #elif defined(XP_WIN) HWND win = parentWidget; #elif defined(XP_MACOSX) # warning IMPLEMENT ME #else #error You lose! #endif #if !defined(XP_MACOSX) baseWindow->InitWindow(win, 0, 0, 0, 0, 0); baseWindow->Create(); baseWindow->SetVisibility(PR_TRUE); #endif return true; } bool TabChild::destroyWidget() { nsCOMPtr baseWindow = do_QueryInterface(mWebNav); if (baseWindow) baseWindow->Destroy(); return true; } TabChild::~TabChild() { destroyWidget(); nsCOMPtr webBrowser = do_QueryInterface(mWebNav); if (webBrowser) { webBrowser->SetContainerWindow(nsnull); } } bool TabChild::RecvloadURL(const nsCString& uri) { printf("loading %s, %d\n", uri.get(), NS_IsMainThread()); nsresult rv = mWebNav->LoadURI(NS_ConvertUTF8toUTF16(uri).get(), nsIWebNavigation::LOAD_FLAGS_NONE, NULL, NULL, NULL); if (NS_FAILED(rv)) { NS_WARNING("mWebNav->LoadURI failed. Eating exception, what else can I do?"); } return true; } bool TabChild::Recvmove(const PRUint32& x, const PRUint32& y, const PRUint32& width, const PRUint32& height) { printf("[TabChild] MOVE to (x,y)=(%ud, %ud), (w,h)= (%ud, %ud)\n", x, y, width, height); nsCOMPtr baseWin = do_QueryInterface(mWebNav); baseWin->SetPositionAndSize(x, y, width, height, PR_TRUE); return true; } bool TabChild::Recvactivate() { nsCOMPtr browser = do_QueryInterface(mWebNav); browser->Activate(); return true; } bool TabChild::RecvsendMouseEvent(const nsString& aType, const PRInt32& aX, const PRInt32& aY, const PRInt32& aButton, const PRInt32& aClickCount, const PRInt32& aModifiers, const bool& aIgnoreRootScrollFrame) { nsCOMPtr window = do_GetInterface(mWebNav); nsCOMPtr utils = do_GetInterface(window); NS_ENSURE_TRUE(utils, true); utils->SendMouseEvent(aType, aX, aY, aButton, aClickCount, aModifiers, aIgnoreRootScrollFrame); 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) { return new mozilla::ipc::DocumentRendererChild(); } bool TabChild::DeallocPDocumentRenderer(PDocumentRendererChild* actor) { delete actor; return true; } bool TabChild::RecvPDocumentRendererConstructor( mozilla::ipc::PDocumentRendererChild *__a, const PRInt32& aX, const PRInt32& aY, const PRInt32& aW, const PRInt32& aH, const nsString& bgcolor, const PRUint32& flags, const bool& flush) { mozilla::ipc::DocumentRendererChild *render = static_cast(__a); nsCOMPtr browser = do_QueryInterface(mWebNav); if (!browser) return true; // silently ignore nsCOMPtr window; if (NS_FAILED(browser->GetContentDOMWindow(getter_AddRefs(window))) || !window) { return true; // silently ignore } PRUint32 width, height; nsCString data; bool ret = render->RenderDocument(window, aX, aY, aW, aH, bgcolor, flags, flush, width, height, data); if (!ret) return true; // silently ignore return PDocumentRendererChild::Send__delete__(__a, width, height, data); } bool TabChild::RecvactivateFrameEvent(const nsString& aType, const bool& capture) { nsCOMPtr window = do_GetInterface(mWebNav); NS_ENSURE_TRUE(window, true); nsCOMPtr chromeHandler = do_QueryInterface(window->GetChromeEventHandler()); NS_ENSURE_TRUE(chromeHandler, true); nsRefPtr listener = new ContentListener(this); NS_ENSURE_TRUE(listener, true); chromeHandler->AddEventListener(aType, listener, capture); return true; }