/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "MPL"); you may not use this file except in * compliance with the MPL. You may obtain a copy of the NPL at * http://www.mozilla.org/NPL/ * * Software distributed under the NPL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL * for the specific language governing rights and limitations under the * NPL. * * The Initial Developer of the Original Code is Alexander. Portions * created by Alexander Larsson are Copyright (C) 1999 * Alexander Larsson. All Rights Reserved. */ #include "GtkMozillaContainer.h" #include "nsRepository.h" #include "nsIBaseWindow.h" #include "nsIWebShell.h" #include "nsIWebNavigation.h" #include "nsIURL.h" #include "nsIIOService.h" #include "nsIServiceManager.h" #include "nsNetUtil.h" #include "nsFileSpec.h" #include "nsIDocumentLoader.h" #include "nsIDocumentLoaderFactory.h" #include "nsIContentViewer.h" #include "prprf.h" #include "nsIPref.h" static NS_DEFINE_CID(kWebShellCID, NS_WEB_SHELL_CID); static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID); GtkMozillaContainer::GtkMozillaContainer(GtkMozilla *moz, nsIPref * aPrefs) { mWebShell = nsnull; width = height = 0; mStream = nsnull; mChannel = nsnull; mLoadGroup = nsnull; mContext = nsnull; mMozArea = nsnull; mSuperWin = nsnull; mozilla = moz; gtk_widget_set_app_paintable(GTK_WIDGET(moz), PR_TRUE); mPrefs = aPrefs; NS_IF_ADDREF(mPrefs); } GtkMozillaContainer::~GtkMozillaContainer(void) { NS_IF_RELEASE(mWebShell); NS_IF_RELEASE(mPrefs); } void GtkMozillaContainer::Show() { GtkAllocation *alloc = >K_WIDGET(mozilla)->allocation; // g_print("GtkMozillaContainer::Show\n"); nsresult rv = nsRepository::CreateInstance(kWebShellCID, nsnull, NS_GET_IID(nsIWebShell), (void**) &mWebShell); if (NS_FAILED(rv) || !mWebShell) { printf("Cannot create WebShell!\n"); return; } if (mozilla) { width = alloc->width; height = alloc->height; // we need to create the mozbox here that will shim // between the superwin and the widget. mMozArea = gtk_mozarea_new(); gtk_container_add(GTK_CONTAINER(mozilla), mMozArea); gtk_widget_realize(mMozArea); gtk_widget_show(mMozArea); mSuperWin = GTK_MOZAREA(mMozArea)->superwin; #ifdef TRAVIS_FIX_ME //printf("Init, size: %d, %d\n", width, height); mWebShell->Init((nsNativeWidget *)mSuperWin, 0, 0, width, height); #endif mWebShell->SetContainer(this); } gdk_window_show(mSuperWin->bin_window); gdk_window_show(mSuperWin->shell_window); if (mWebShell) { nsCOMPtr window = do_QueryInterface(mWebShell); if (window) { window->SetVisibility(PR_TRUE); } } } void GtkMozillaContainer::Resize(gint w, gint h) { GtkAllocation alloc; // g_print("GtkMozillaContainer::Resize called width: %d, %d\n", w, h); if (mWebShell) { width = w; height = h; //printf("GtkMozillaContainer::Resize setting to: %d, %d\n", width, height); alloc.x = GTK_WIDGET(mozilla)->allocation.x; alloc.y = GTK_WIDGET(mozilla)->allocation.y; alloc.width = w; alloc.height = h; // gtk_widget_size_allocate(GTK_WIDGET(mozilla), &alloc); gdk_superwin_resize(mSuperWin, width, height); nsCOMPtr window = do_QueryInterface(mWebShell); if (window) { window->SetPositionAndSize(0, 0, width, height, PR_FALSE); } } } void GtkMozillaContainer::LoadURL(const gchar *url) { PRUnichar *u_url; int len, i; len = strlen(url); u_url = new (PRUnichar)[len+1]; for (i=0;iLoadURL(u_url); delete [] u_url; } void GtkMozillaContainer::Stop() { nsCOMPtr webNav(do_QueryInterface(mWebShell)); webNav->Stop(); } void GtkMozillaContainer::Reload(GtkMozillaReloadType type) { nsCOMPtr webNav(do_QueryInterface(mWebShell)); webNav->Reload(nsIWebNavigation::reloadNormal); } gint GtkMozillaContainer::Back() { #ifdef TRAVIS_FIX_ME return NS_SUCCEEDED(mWebShell->Back()); #else return 0; #endif } gint GtkMozillaContainer::CanBack() { #ifdef TRAVIS_FIX_ME return mWebShell->CanBack()==NS_OK; #else return 0; #endif } gint GtkMozillaContainer::Forward() { #ifdef TRAVIS_FIX_ME return NS_SUCCEEDED(mWebShell->Forward()); #else return 0; #endif } gint GtkMozillaContainer::CanForward() { #ifdef TRAVIS_FIX_ME return mWebShell->CanForward()==NS_OK; #else return 0; #endif } gint GtkMozillaContainer::GoTo(gint history_index) { return NS_SUCCEEDED(mWebShell->GoTo((PRInt32)history_index)); } gint GtkMozillaContainer::GetHistoryLength() { PRInt32 Result; if (NS_SUCCEEDED(mWebShell->GetHistoryLength(Result))) return (gint) Result; else return 0; } gint GtkMozillaContainer::GetHistoryIndex() { PRInt32 Result; if (NS_SUCCEEDED(mWebShell->GetHistoryIndex(Result))) return (gint) Result; else return 0; } NS_IMETHODIMP GtkMozillaContainer::QueryInterface(REFNSIID aIID, void** aInstancePtr) { if (NULL == aInstancePtr) { return NS_ERROR_NULL_POINTER; } nsISupports *ifp = nsnull; if (aIID.Equals(NS_GET_IID(nsIWebShellContainer))) { ifp = (nsIWebShellContainer*)this; } else if(aIID.Equals(NS_GET_IID(nsISupports))) { ifp = this; } else { *aInstancePtr = 0; return NS_NOINTERFACE; } *aInstancePtr = (void *)ifp; NS_ADDREF(ifp); return NS_OK; } nsrefcnt GtkMozillaContainer::AddRef() { // This object is not reference counted so we just return a number > 0 return 3; } nsrefcnt GtkMozillaContainer::Release() { // This object is not reference counted so we just return a number > 0 return 2; } static char *simple_unicode_to_char(const PRUnichar* aURL) { int i; int len=0; const PRUnichar* ptr; char *str; ptr=aURL; while (*ptr++) len++; str = (char *)malloc(len+1); if (str==NULL) return NULL; for (i=0;iCreateInstance(aCommand, aChannel, aLoadGroup, aContentType, aContainer, aExtraInfo, aDocListenerResult, aDocViewerResult); NS_RELEASE(factory); return rv; } NS_IMETHODIMP GtkMozillaContainer::ProgressLoadURL(nsIWebShell* aShell, const PRUnichar* aURL, PRInt32 aProgress, PRInt32 aProgressMax) { printf("Progress: %d (0..%d)\n", aProgress, aProgressMax); return NS_OK; } NS_IMETHODIMP GtkMozillaContainer::NewWebShell(PRUint32 aChromeMask, PRBool aVisible, nsIWebShell *&aNewWebShell) { printf("NewWebShell\n"); aNewWebShell = nsnull; return NS_ERROR_FAILURE; } NS_IMETHODIMP GtkMozillaContainer::FindWebShellWithName(const PRUnichar* aName, nsIWebShell*& aResult) { printf("FindWebShellWithName\n"); aResult = nsnull; #ifdef TRAVIS_FIX_ME if (NS_OK == mWebShell->FindChildWithName(aName, aResult)) { if (nsnull != aResult) { return NS_OK; } } #endif return NS_OK; } NS_IMETHODIMP GtkMozillaContainer::ContentShellAdded(nsIWebShell* aChildShell, nsIContent* frameNode) { printf("ContentShellAdded\n"); return NS_ERROR_FAILURE; } NS_IMETHODIMP GtkMozillaContainer::CreatePopup(nsIDOMElement* aElement, nsIDOMElement* aPopupContent, PRInt32 aXPos, PRInt32 aYPos, const nsString& aPopupType, const nsString& anAnchorAlignment, const nsString& aPopupAlignment, nsIDOMWindow* aWindow, nsIDOMWindow** outPopup) { printf("CreatePopup\n"); return NS_ERROR_FAILURE; } NS_IMETHODIMP GtkMozillaContainer::CanCreateNewWebShell(PRBool& aResult) { printf("CanCreateNewWebShell\n"); return NS_ERROR_FAILURE; } NS_IMETHODIMP GtkMozillaContainer::SetNewWebShellInfo(const nsString& aName, const nsString& anURL, nsIWebShell* aOpenerShell, PRUint32 aChromeMask, nsIWebShell** aNewShell, nsIWebShell** anInnerShell) { printf("SetNewWebShellInfo\n"); return NS_ERROR_FAILURE; } NS_IMETHODIMP GtkMozillaContainer::ChildShellAdded(nsIWebShell** aChildShell, nsIContent* frameNode) { printf("ChildShellAdded\n"); return NS_ERROR_FAILURE; } NS_IMETHODIMP GtkMozillaContainer::FocusAvailable(nsIWebShell* aFocusedWebShell, PRBool& aFocusTaken) { printf("FocusAvailable\n"); return NS_ERROR_FAILURE; } gint GtkMozillaContainer::StartStream(const char *base_url, const char *action, nsISupports * ctxt, const char *content_type) { nsresult rv = NS_OK; nsIURI* url = nsnull; nsIContentViewer* viewer = nsnull; nsString url_str(base_url); nsIInputStream *istream = NULL; mStream = new GtkMozillaInputStream(); if (mStream == nsnull) goto error; NS_ADDREF(mStream); /* Own this */ rv = CallQueryInterface(mStream, &istream); if (NS_FAILED(rv)) goto error; rv = NS_NewURI(&url, url_str, NULL); if (NS_FAILED(rv)) goto error; rv = NS_NewLoadGroup(&mLoadGroup, nsnull); if (NS_FAILED(rv)) goto error; rv = NS_NewInputStreamChannel(&mChannel, url, istream, content_type, 1024/*len*/); if (NS_FAILED(rv)) goto error; rv = mChannel->SetLoadGroup(mLoadGroup); if (NS_FAILED(rv)) goto error; NS_RELEASE(istream); rv = CreateContentViewer(action, mChannel, mLoadGroup, content_type, mWebShell, nsnull, &mListener, &viewer); if (NS_FAILED(rv)) { printf("GtkMozillaContainer: Unable to create ContentViewer for action=%s, content-type=%s\n", action, content_type); goto error; } rv = viewer->SetContainer((nsIContentViewerContainer*)mWebShell); if (NS_FAILED(rv)) goto error; rv = mWebShell->Embed(viewer, action, nsnull); if (NS_FAILED(rv)) goto error; /* * Pass the OnStartRequest(...) notification out to the document * IStreamListener. */ rv = mListener->OnStartRequest(mChannel, ctxt); if (NS_FAILED(rv)) goto error; mContext = ctxt; NS_IF_RELEASE(viewer); if (NS_SUCCEEDED(rv)) return 0; else return -1; error: if (mStream != NULL) { delete mStream; mStream = NULL; } NS_IF_RELEASE(istream); NS_IF_RELEASE(url); NS_IF_RELEASE(mLoadGroup); NS_IF_RELEASE(mChannel); NS_IF_RELEASE(viewer); NS_IF_RELEASE(mListener); return -1; } gint GtkMozillaContainer::WriteStream(const char *data, gint offset, gint len) { nsresult rv = NS_OK; PRUint32 Count; mStream->Fill(data, len); rv = mListener->OnDataAvailable(mChannel, mContext, mStream, offset, len); if (NS_FAILED(rv)) return 0; // Busted in NECKO // rv = mListener->OnProgress(mChannel, len, len+1); if (NS_FAILED(rv)) return 0; mStream->FillResult(&Count); return (gint) Count; } void GtkMozillaContainer::EndStream(void) { nsresult rv = NS_OK; mStream->Fill(NULL, 0); rv = mListener->OnDataAvailable(mChannel, mContext, mStream, 0, 0); if (NS_FAILED(rv)) return; rv = mListener->OnStopRequest(mChannel, mContext, NS_OK, NULL); if (NS_FAILED(rv)) return; // Busted in NECKO // rv = mListener->OnProgress(mChannel, 10, 10); if (NS_FAILED(rv)) return; NS_IF_RELEASE(mChannel); NS_IF_RELEASE(mLoadGroup); NS_IF_RELEASE(mListener); NS_IF_RELEASE(mStream); }