diff options
author | Christian Persch <chpe@src.gnome.org> | 2007-08-26 04:59:04 +0800 |
---|---|---|
committer | Christian Persch <chpe@src.gnome.org> | 2007-08-26 04:59:04 +0800 |
commit | 6deabce61b1758b0c395678bf5c2769ee4ca17c6 (patch) | |
tree | 27866c89b34cb0fe866753fbef2894e6dfd01785 /embed/xulrunner/src | |
parent | d2bc7076ca31996d4a5b80b74e4380e6f2f56321 (diff) | |
download | gsoc2013-epiphany-6deabce61b1758b0c395678bf5c2769ee4ca17c6.tar gsoc2013-epiphany-6deabce61b1758b0c395678bf5c2769ee4ca17c6.tar.gz gsoc2013-epiphany-6deabce61b1758b0c395678bf5c2769ee4ca17c6.tar.bz2 gsoc2013-epiphany-6deabce61b1758b0c395678bf5c2769ee4ca17c6.tar.lz gsoc2013-epiphany-6deabce61b1758b0c395678bf5c2769ee4ca17c6.tar.xz gsoc2013-epiphany-6deabce61b1758b0c395678bf5c2769ee4ca17c6.tar.zst gsoc2013-epiphany-6deabce61b1758b0c395678bf5c2769ee4ca17c6.zip |
Initial checkin: merged embed/gecko from xulrunner branch to embed/xulrunner, and svn copied embed/mozilla to embed/xulrunner/embed. Not integreated with the build yet.
svn path=/trunk/; revision=7297
Diffstat (limited to 'embed/xulrunner/src')
42 files changed, 6810 insertions, 0 deletions
diff --git a/embed/xulrunner/src/AutoJSContextStack.cpp b/embed/xulrunner/src/AutoJSContextStack.cpp new file mode 100644 index 000000000..1e02b60fd --- /dev/null +++ b/embed/xulrunner/src/AutoJSContextStack.cpp @@ -0,0 +1,48 @@ +/* + * Copyright © 2006 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id$ + */ + +#include <mozilla-config.h> +#include "config.h" + +#include "AutoJSContextStack.h" + +#include <nsIServiceManager.h> +#include <nsServiceManagerUtils.h> + +AutoJSContextStack::~AutoJSContextStack() +{ + if (mStack) { + JSContext* cx; + mStack->Pop (&cx); + + NS_ASSERTION(cx == nsnull, "We pushed a null context but popped a non-null context!?"); + } +} + +nsresult +AutoJSContextStack::Init() +{ + nsresult rv; + mStack = do_GetService ("@mozilla.org/js/xpc/ContextStack;1", &rv); + if (NS_FAILED (rv)) + return rv; + + return mStack->Push (nsnull); +} diff --git a/embed/xulrunner/src/AutoJSContextStack.h b/embed/xulrunner/src/AutoJSContextStack.h new file mode 100644 index 000000000..5294e7d4e --- /dev/null +++ b/embed/xulrunner/src/AutoJSContextStack.h @@ -0,0 +1,41 @@ +/* + * Copyright © 2006 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id$ + */ + +#ifndef AUTO_JSCONTEXTSTACK_H +#define AUTO_JSCONTEXTSTACK_H + +struct JSContext; + +#include <nsCOMPtr.h> +#include <nsIJSContextStack.h> + +class AutoJSContextStack +{ + public: + AutoJSContextStack () { } + ~AutoJSContextStack (); + + nsresult Init (); + + private: + nsCOMPtr<nsIJSContextStack> mStack; +}; + +#endif diff --git a/embed/xulrunner/src/AutoWindowModalState.cpp b/embed/xulrunner/src/AutoWindowModalState.cpp new file mode 100644 index 000000000..ca7596b38 --- /dev/null +++ b/embed/xulrunner/src/AutoWindowModalState.cpp @@ -0,0 +1,43 @@ +/* + * Copyright © 2006 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id$ + */ + +#include <mozilla-config.h> +#include "config.h" + +#include "AutoWindowModalState.h" + +AutoWindowModalState::AutoWindowModalState (nsIDOMWindow *aWindow) +{ +#ifdef HAVE_GECKO_1_9 + mWindow = do_QueryInterface (aWindow); + if (mWindow) { + mWindow->EnterModalState (); + } +#endif +} + +AutoWindowModalState::~AutoWindowModalState() +{ +#ifdef HAVE_GECKO_1_9 + if (mWindow) { + mWindow->LeaveModalState (); + } +#endif +} diff --git a/embed/xulrunner/src/AutoWindowModalState.h b/embed/xulrunner/src/AutoWindowModalState.h new file mode 100644 index 000000000..bccefede2 --- /dev/null +++ b/embed/xulrunner/src/AutoWindowModalState.h @@ -0,0 +1,38 @@ +/* + * Copyright © 2006 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id$ + */ + +#ifndef AUTO_WINDOWMODALSTATE_H +#define AUTO_WINDOWMODALSTATE_H + +#include <nsCOMPtr.h> +#include <nsPIDOMWindow.h> + +class AutoWindowModalState +{ + public: + AutoWindowModalState (nsIDOMWindow *); + ~AutoWindowModalState (); + + private: + + nsCOMPtr<nsPIDOMWindow> mWindow; +}; + +#endif diff --git a/embed/xulrunner/src/EmbedContentListener.cpp b/embed/xulrunner/src/EmbedContentListener.cpp new file mode 100644 index 000000000..8a3280488 --- /dev/null +++ b/embed/xulrunner/src/EmbedContentListener.cpp @@ -0,0 +1,159 @@ +/* + * Copyright © Christopher Blizzard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * --------------------------------------------------------------------------- + * Derived from Mozilla.org code, which had the following attributions: + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright © Christopher Blizzard. All Rights Reserved. + * Portions created by the Initial Developer are Copyright © 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Christopher Blizzard <blizzard@mozilla.org> + * --------------------------------------------------------------------------- + * + * $Id$ + */ + +#include <mozilla-config.h> +#include "config.h" + +#include <strings.h> + +#include "nsIURI.h" +#include <nsMemory.h> + +#include "EmbedContentListener.h" +#include "GeckoBrowser.h" +#include "gecko-embed-signals.h" + +#include "nsServiceManagerUtils.h" +#include "nsIWebNavigationInfo.h" +#include "nsDocShellCID.h" + +EmbedContentListener::EmbedContentListener(void) +{ + mOwner = nsnull; +} + +EmbedContentListener::~EmbedContentListener() +{ +} + +NS_IMPL_ISUPPORTS2(EmbedContentListener, + nsIURIContentListener, + nsISupportsWeakReference) + +nsresult +EmbedContentListener::Init(GeckoBrowser *aOwner) +{ + mOwner = aOwner; + return NS_OK; +} + +NS_IMETHODIMP +EmbedContentListener::OnStartURIOpen(nsIURI *aURI, + PRBool *aAbortOpen) +{ + nsresult rv; + + nsEmbedCString specString; + rv = aURI->GetSpec(specString); + + if (NS_FAILED(rv)) + return rv; + + gboolean retval = FALSE; + g_signal_emit (mOwner->mOwningWidget, + gecko_embed_signals[OPEN_URI], 0, + specString.get(), &retval); + + *aAbortOpen = retval; + + return NS_OK; +} + +NS_IMETHODIMP +EmbedContentListener::DoContent(const char *aContentType, + PRBool aIsContentPreferred, + nsIRequest *aRequest, + nsIStreamListener **aContentHandler, + PRBool *aAbortProcess) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +EmbedContentListener::IsPreferred(const char *aContentType, + char **aDesiredContentType, + PRBool *aCanHandleContent) +{ + return CanHandleContent(aContentType, PR_TRUE, aDesiredContentType, + aCanHandleContent); +} + +NS_IMETHODIMP +EmbedContentListener::CanHandleContent(const char *aContentType, + PRBool aIsContentPreferred, + char **aDesiredContentType, + PRBool *_retval) +{ + *_retval = PR_FALSE; + *aDesiredContentType = nsnull; + + if (aContentType) { + nsCOMPtr<nsIWebNavigationInfo> webNavInfo( + do_GetService(NS_WEBNAVIGATION_INFO_CONTRACTID)); + if (webNavInfo) { + PRUint32 canHandle; + nsresult rv = + webNavInfo->IsTypeSupported(nsDependentCString(aContentType), + mOwner ? mOwner->mNavigation.get() : nsnull, + &canHandle); + NS_ENSURE_SUCCESS(rv, rv); + *_retval = (canHandle != nsIWebNavigationInfo::UNSUPPORTED); + } + } + return NS_OK; +} + +NS_IMETHODIMP +EmbedContentListener::GetLoadCookie(nsISupports **aLoadCookie) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +EmbedContentListener::SetLoadCookie(nsISupports *aLoadCookie) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +EmbedContentListener::GetParentContentListener(nsIURIContentListener **aParent) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +EmbedContentListener::SetParentContentListener(nsIURIContentListener *aParent) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} diff --git a/embed/xulrunner/src/EmbedContentListener.h b/embed/xulrunner/src/EmbedContentListener.h new file mode 100644 index 000000000..427d8263e --- /dev/null +++ b/embed/xulrunner/src/EmbedContentListener.h @@ -0,0 +1,63 @@ +/* + * Copyright © Christopher Blizzard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * --------------------------------------------------------------------------- + * Derived from Mozilla.org code, which had the following attributions: + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright © Christopher Blizzard. All Rights Reserved. + * Portions created by the Initial Developer are Copyright © 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Christopher Blizzard <blizzard@mozilla.org> + * --------------------------------------------------------------------------- + * + * $Id$ + */ + +#ifndef __EmbedContentListener_h +#define __EmbedContentListener_h + +#include <nsIURIContentListener.h> +#include <nsWeakReference.h> + +class GeckoBrowser; + +class EmbedContentListener : public nsIURIContentListener, + public nsSupportsWeakReference +{ + public: + + EmbedContentListener(); + virtual ~EmbedContentListener(); + + nsresult Init (GeckoBrowser *aOwner); + + NS_DECL_ISUPPORTS + + NS_DECL_NSIURICONTENTLISTENER + + private: + + GeckoBrowser *mOwner; + +}; + +#endif /* __EmbedContentListener_h */ diff --git a/embed/xulrunner/src/EmbedEventListener.cpp b/embed/xulrunner/src/EmbedEventListener.cpp new file mode 100644 index 000000000..e4803b8bd --- /dev/null +++ b/embed/xulrunner/src/EmbedEventListener.cpp @@ -0,0 +1,183 @@ +/* + * Copyright © Christopher Blizzard + * Copyright © 2006 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * --------------------------------------------------------------------------- + * Derived from Mozilla.org code, which had the following attributions: + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright © Christopher Blizzard. All Rights Reserved. + * Portions created by the Initial Developer are Copyright © 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Christopher Blizzard <blizzard@mozilla.org> + * --------------------------------------------------------------------------- + * + * $Id$ + */ + +#include <mozilla-config.h> +#include "config.h" + +#include <nsCOMPtr.h> +#include <nsIDOMMouseEvent.h> + +#include "nsIDOMKeyEvent.h" +#include "nsIDOMUIEvent.h" + +#include "EmbedEventListener.h" +#include "GeckoBrowser.h" + +#include "gecko-embed-signals.h" +#include "gecko-dom-event.h" +#include "gecko-dom-event-internal.h" +#include "gecko-dom-event-private.h" + +EmbedEventListener::EmbedEventListener(GeckoBrowser *aOwner) + : mOwner(aOwner) +{ +} + +EmbedEventListener::~EmbedEventListener() +{ +} + +NS_IMPL_ADDREF(EmbedEventListener) +NS_IMPL_RELEASE(EmbedEventListener) +NS_INTERFACE_MAP_BEGIN(EmbedEventListener) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMKeyListener) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIDOMEventListener, nsIDOMKeyListener) + NS_INTERFACE_MAP_ENTRY(nsIDOMKeyListener) + NS_INTERFACE_MAP_ENTRY(nsIDOMMouseListener) + NS_INTERFACE_MAP_ENTRY(nsIDOMUIListener) + NS_INTERFACE_MAP_ENTRY(nsIDOMContextMenuListener) +NS_INTERFACE_MAP_END + +inline NS_METHOD +EmbedEventListener::Emit(nsIDOMEvent *aDOMEvent, + GeckoEmbedSignals signal, + GeckoDOMEventType type) +{ + if (!aDOMEvent) + return NS_OK; + + // g_print ("Emitting signal '%s'\n", g_signal_name (gecko_embed_signals[signal])); + + /* Check if there are any handlers connected */ + if (!g_signal_has_handler_pending (mOwner->mOwningWidget, + gecko_embed_signals[signal], + 0, FALSE /* FIXME: correct? */)) { + return NS_OK; + } + + GeckoDOMEvent event; + GECKO_DOM_EVENT_STATIC_INIT (event, aDOMEvent); + + gboolean retval = FALSE; + g_signal_emit (mOwner->mOwningWidget, + gecko_embed_signals[signal], 0, + (GeckoDOMEvent*) &event, &retval); + if (retval) { + aDOMEvent->StopPropagation(); + aDOMEvent->PreventDefault(); + } + + GECKO_DOM_EVENT_STATIC_DEINIT (event); + + return NS_OK; +} + +NS_IMETHODIMP +EmbedEventListener::KeyDown(nsIDOMEvent* aDOMEvent) +{ + return Emit(aDOMEvent, DOM_KEY_DOWN, TYPE_KEY_EVENT); +} + +NS_IMETHODIMP +EmbedEventListener::KeyPress(nsIDOMEvent* aDOMEvent) +{ + return Emit(aDOMEvent, DOM_KEY_PRESS, TYPE_KEY_EVENT); +} + +NS_IMETHODIMP +EmbedEventListener::KeyUp(nsIDOMEvent* aDOMEvent) +{ + return Emit(aDOMEvent, DOM_KEY_UP, TYPE_KEY_EVENT); +} + +NS_IMETHODIMP +EmbedEventListener::MouseDown(nsIDOMEvent* aDOMEvent) +{ + return Emit(aDOMEvent, DOM_MOUSE_DOWN, TYPE_MOUSE_EVENT); +} + +NS_IMETHODIMP +EmbedEventListener::MouseUp(nsIDOMEvent* aDOMEvent) +{ + return Emit(aDOMEvent, DOM_MOUSE_UP, TYPE_MOUSE_EVENT); +} + +NS_IMETHODIMP +EmbedEventListener::MouseClick(nsIDOMEvent* aDOMEvent) +{ + return Emit(aDOMEvent, DOM_MOUSE_CLICK, TYPE_MOUSE_EVENT); +} + +NS_IMETHODIMP +EmbedEventListener::MouseDblClick(nsIDOMEvent* aDOMEvent) +{ + return Emit(aDOMEvent, DOM_MOUSE_DOUBLE_CLICK, TYPE_MOUSE_EVENT); +} + +NS_IMETHODIMP +EmbedEventListener::MouseOver(nsIDOMEvent* aDOMEvent) +{ + return Emit(aDOMEvent, DOM_MOUSE_OVER, TYPE_MOUSE_EVENT); +} + +NS_IMETHODIMP +EmbedEventListener::MouseOut(nsIDOMEvent* aDOMEvent) +{ + return Emit(aDOMEvent, DOM_MOUSE_OUT, TYPE_MOUSE_EVENT); +} + +NS_IMETHODIMP +EmbedEventListener::FocusIn(nsIDOMEvent* aDOMEvent) +{ + return Emit(aDOMEvent, DOM_FOCUS_IN, TYPE_UI_EVENT); +} + +NS_IMETHODIMP +EmbedEventListener::FocusOut(nsIDOMEvent* aDOMEvent) +{ + return Emit(aDOMEvent, DOM_FOCUS_OUT, TYPE_UI_EVENT); +} + +NS_IMETHODIMP +EmbedEventListener::Activate(nsIDOMEvent* aDOMEvent) +{ + return Emit(aDOMEvent, DOM_ACTIVATE, TYPE_UI_EVENT); +} + +NS_IMETHODIMP +EmbedEventListener::ContextMenu(nsIDOMEvent* aDOMEvent) +{ + return Emit(aDOMEvent, DOM_CONTEXT_MENU, TYPE_MOUSE_EVENT); +} diff --git a/embed/xulrunner/src/EmbedEventListener.h b/embed/xulrunner/src/EmbedEventListener.h new file mode 100644 index 000000000..e1ea99d31 --- /dev/null +++ b/embed/xulrunner/src/EmbedEventListener.h @@ -0,0 +1,102 @@ +/* + * Copyright © Christopher Blizzard + * Copyright © 2006 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * --------------------------------------------------------------------------- + * Derived from Mozilla.org code, which had the following attributions: + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright © Christopher Blizzard. All Rights Reserved. + * Portions created by the Initial Developer are Copyright © 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Christopher Blizzard <blizzard@mozilla.org> + * --------------------------------------------------------------------------- + * + * $Id$ + */ + +#ifndef __EmbedEventListener_h +#define __EmbedEventListener_h + +#include <nsIDOMKeyListener.h> +#include <nsIDOMMouseListener.h> +#include <nsIDOMUIListener.h> +#include <nsIDOMContextMenuListener.h> + +#include <gecko-embed-signals.h> + +class GeckoBrowser; + +class EmbedEventListener : public nsIDOMKeyListener, + public nsIDOMMouseListener, + public nsIDOMUIListener, + public nsIDOMContextMenuListener +{ + public: + + EmbedEventListener(GeckoBrowser *aOwner); + virtual ~EmbedEventListener(); + + NS_DECL_ISUPPORTS + + // nsIDOMEventListener + + NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) { return NS_OK; } + + // nsIDOMKeyListener + + NS_IMETHOD KeyDown(nsIDOMEvent* aDOMEvent); + NS_IMETHOD KeyUp(nsIDOMEvent* aDOMEvent); + NS_IMETHOD KeyPress(nsIDOMEvent* aDOMEvent); + + // nsIDOMMouseListener + + NS_IMETHOD MouseDown(nsIDOMEvent* aDOMEvent); + NS_IMETHOD MouseUp(nsIDOMEvent* aDOMEvent); + NS_IMETHOD MouseClick(nsIDOMEvent* aDOMEvent); + NS_IMETHOD MouseDblClick(nsIDOMEvent* aDOMEvent); + NS_IMETHOD MouseOver(nsIDOMEvent* aDOMEvent); + NS_IMETHOD MouseOut(nsIDOMEvent* aDOMEvent); + + // nsIDOMUIListener + + NS_IMETHOD Activate(nsIDOMEvent* aDOMEvent); + NS_IMETHOD FocusIn(nsIDOMEvent* aDOMEvent); + NS_IMETHOD FocusOut(nsIDOMEvent* aDOMEvent); + + // nsIDOMContextMenuListener + NS_IMETHOD ContextMenu(nsIDOMEvent *aDOMEvent); + + private: + GeckoBrowser *mOwner; + + enum GeckoDOMEventType { + TYPE_KEY_EVENT, + TYPE_MOUSE_EVENT, + TYPE_UI_EVENT + }; + + NS_METHOD Emit(nsIDOMEvent *aDOMEvent, + GeckoEmbedSignals signal, + GeckoDOMEventType); +}; + +#endif /* __EmbedEventListener_h */ diff --git a/embed/xulrunner/src/EmbedProgress.cpp b/embed/xulrunner/src/EmbedProgress.cpp new file mode 100644 index 000000000..d31e9f850 --- /dev/null +++ b/embed/xulrunner/src/EmbedProgress.cpp @@ -0,0 +1,224 @@ +/* + * Copyright © Christopher Blizzard + * Copyright © 2006 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * --------------------------------------------------------------------------- + * Derived from Mozilla.org code, which had the following attributions: + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright © Christopher Blizzard. All Rights Reserved. + * Portions created by the Initial Developer are Copyright © 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Christopher Blizzard <blizzard@mozilla.org> + * --------------------------------------------------------------------------- + * + * $Id$ + */ + +#include <mozilla-config.h> +#include "config.h" + +#include "EmbedProgress.h" + +#include <nsIChannel.h> +#include <nsIWebProgress.h> +#include <nsIDOMWindow.h> + +#include "nsIURI.h" +#include "nsMemory.h" + +#include "gecko-embed-types.h" + +#include "gecko-embed-signals.h" + +EmbedProgress::EmbedProgress() +: mOwner(nsnull) +{ +} + +EmbedProgress::~EmbedProgress() +{ +} + +/* FIXME implement nsIWebProgressListener2 */ +NS_IMPL_ISUPPORTS2(EmbedProgress, + nsIWebProgressListener, + nsISupportsWeakReference) + +nsresult +EmbedProgress::Init(GeckoBrowser *aOwner) +{ + mOwner = aOwner; + return NS_OK; +} + +NS_IMETHODIMP +EmbedProgress::OnStateChange(nsIWebProgress *aWebProgress, + nsIRequest *aRequest, + PRUint32 aStateFlags, + nsresult aStatus) +{ + // give the widget a chance to attach any listeners + mOwner->ContentStateChange(); + // if we've got the start flag, emit the signal + if ((aStateFlags & GECKO_EMBED_FLAG_IS_NETWORK) && + (aStateFlags & GECKO_EMBED_FLAG_START)) + { + g_signal_emit (mOwner->mOwningWidget, gecko_embed_signals[NET_START], 0); + } + + nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest); + if (!channel) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIURI> requestURI; + channel->GetURI(getter_AddRefs(requestURI)); + if (!requestURI) return NS_ERROR_FAILURE; + + if (IsCurrentURI(requestURI)) + { + // for people who know what they are doing + g_signal_emit (mOwner->mOwningWidget, + gecko_embed_signals[NET_STATE], 0, + aStateFlags, aStatus); + } + + nsEmbedCString uriString; + requestURI->GetSpec(uriString); + g_signal_emit (mOwner->mOwningWidget, gecko_embed_signals[NET_STATE_ALL], 0, + uriString.get(), (gint)aStateFlags, (gint)aStatus); + // and for stop, too + if ((aStateFlags & GECKO_EMBED_FLAG_IS_NETWORK) && + (aStateFlags & GECKO_EMBED_FLAG_STOP)) + { + g_signal_emit (mOwner->mOwningWidget, gecko_embed_signals[NET_STOP], 0); + // let our owner know that the load finished + mOwner->ContentFinishedLoading(); + } + + return NS_OK; +} + +NS_IMETHODIMP +EmbedProgress::OnProgressChange(nsIWebProgress *aWebProgress, + nsIRequest *aRequest, + PRInt32 aCurSelfProgress, + PRInt32 aMaxSelfProgress, + PRInt32 aCurTotalProgress, + PRInt32 aMaxTotalProgress) +{ + nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest); + if (!channel) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIURI> requestURI; + channel->GetURI(getter_AddRefs(requestURI)); + if (!requestURI) return NS_ERROR_FAILURE; + + // is it the same as the current uri? + if (IsCurrentURI(requestURI)) { + g_signal_emit (mOwner->mOwningWidget, + gecko_embed_signals[PROGRESS], 0, + aCurTotalProgress, aMaxTotalProgress); + } + + nsEmbedCString uriString; + requestURI->GetSpec(uriString); + g_signal_emit (mOwner->mOwningWidget, + gecko_embed_signals[PROGRESS_ALL], 0, + uriString.get(), + aCurTotalProgress, aMaxTotalProgress); + return NS_OK; +} + +NS_IMETHODIMP +EmbedProgress::OnLocationChange(nsIWebProgress *aWebProgress, + nsIRequest *aRequest, + nsIURI *aLocation) +{ + nsEmbedCString newURI; + NS_ENSURE_ARG_POINTER(aLocation); + aLocation->GetSpec(newURI); + + // Make sure that this is the primary frame change and not + // just a subframe. + PRBool isSubFrameLoad = PR_FALSE; + if (aWebProgress) { + nsCOMPtr<nsIDOMWindow> domWindow; + nsCOMPtr<nsIDOMWindow> topDomWindow; + + aWebProgress->GetDOMWindow(getter_AddRefs(domWindow)); + + // get the root dom window + if (domWindow) + domWindow->GetTop(getter_AddRefs(topDomWindow)); + + if (domWindow != topDomWindow) + isSubFrameLoad = PR_TRUE; + } + + if (!isSubFrameLoad) { + mOwner->SetURI(newURI.get()); + g_signal_emit (mOwner->mOwningWidget, gecko_embed_signals[LOCATION], 0); + } + + return NS_OK; +} + +NS_IMETHODIMP +EmbedProgress::OnStatusChange(nsIWebProgress *aWebProgress, + nsIRequest *aRequest, + nsresult aStatus, + const PRUnichar *aMessage) +{ + // need to make a copy so we can safely cast to a void * + nsEmbedString message(aMessage); + PRUnichar *tmpString = NS_StringCloneData(message); + + g_signal_emit (mOwner->mOwningWidget, + gecko_embed_signals[STATUS_CHANGE], 0, + static_cast<void *>(aRequest), + static_cast<int>(aStatus), + static_cast<void *>(tmpString)); + + nsMemory::Free(tmpString); + + return NS_OK; +} + +NS_IMETHODIMP +EmbedProgress::OnSecurityChange(nsIWebProgress *aWebProgress, + nsIRequest *aRequest, + PRUint32 aState) +{ + g_signal_emit (mOwner->mOwningWidget, + gecko_embed_signals[SECURITY_CHANGE], 0, + static_cast<void *>(aRequest), + aState); + return NS_OK; +} + +PRBool +EmbedProgress::IsCurrentURI(nsIURI *aURI) +{ + nsEmbedCString spec; + aURI->GetSpec(spec); + + return strcmp(mOwner->mURI.get(), spec.get()) == 0; +} diff --git a/embed/xulrunner/src/EmbedProgress.h b/embed/xulrunner/src/EmbedProgress.h new file mode 100644 index 000000000..ca4d2187f --- /dev/null +++ b/embed/xulrunner/src/EmbedProgress.h @@ -0,0 +1,63 @@ +/* + * Copyright © Christopher Blizzard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * --------------------------------------------------------------------------- + * Derived from Mozilla.org code, which had the following attributions: + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright © Christopher Blizzard. All Rights Reserved. + * Portions created by the Initial Developer are Copyright © 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Christopher Blizzard <blizzard@mozilla.org> + * --------------------------------------------------------------------------- + * + * $Id$ + */ + +#ifndef __EmbedProgress_h +#define __EmbedProgress_h + +#include <nsIWebProgressListener.h> +#include <nsWeakReference.h> +#include <nsIURI.h> +#include "GeckoBrowser.h" + +class EmbedProgress : public nsIWebProgressListener, + public nsSupportsWeakReference +{ + public: + EmbedProgress(); + virtual ~EmbedProgress(); + + nsresult Init(GeckoBrowser *aOwner); + + NS_DECL_ISUPPORTS + + NS_DECL_NSIWEBPROGRESSLISTENER + + private: + + GeckoBrowser *mOwner; + + PRBool IsCurrentURI(nsIURI *aURI); +}; + +#endif /* __EmbedProgress_h */ diff --git a/embed/xulrunner/src/EmbedStream.cpp b/embed/xulrunner/src/EmbedStream.cpp new file mode 100644 index 000000000..6cd08d400 --- /dev/null +++ b/embed/xulrunner/src/EmbedStream.cpp @@ -0,0 +1,311 @@ +/* + * Copyright © Christopher Blizzard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * --------------------------------------------------------------------------- + * Derived from Mozilla.org code, which had the following attributions: + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright © Christopher Blizzard. All Rights Reserved. + * Portions created by the Initial Developer are Copyright © 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Christopher Blizzard <blizzard@mozilla.org> + * --------------------------------------------------------------------------- + * + * $Id$ + */ + +#include <mozilla-config.h> +#include <config.h> + +#include <nsIPipe.h> +#include <nsIInputStream.h> +#include <nsIOutputStream.h> +#include <nsIContentViewerContainer.h> +#include <nsIDocumentLoaderFactory.h> +#include <nsNetUtil.h> +#include <prmem.h> + +#include "nsXPCOMCID.h" +#include "nsICategoryManager.h" + +#include "nsIContentViewer.h" + +#include "EmbedStream.h" +#include "EmbedPrivate.h" +#include "EmbedWindow.h" +#include "nsReadableUtils.h" + +// nsIInputStream interface + +NS_IMPL_ISUPPORTS1(EmbedStream, nsIInputStream) + +EmbedStream::EmbedStream() +{ + mOwner = nsnull; + mOffset = 0; + mDoingStream = PR_FALSE; +} + +EmbedStream::~EmbedStream() +{ +} + +void +EmbedStream::InitOwner(EmbedPrivate *aOwner) +{ + mOwner = aOwner; +} + +NS_METHOD +EmbedStream::Init(void) +{ + nsresult rv = NS_OK; + + nsCOMPtr<nsIInputStream> bufInStream; + nsCOMPtr<nsIOutputStream> bufOutStream; + + rv = NS_NewPipe(getter_AddRefs(bufInStream), + getter_AddRefs(bufOutStream)); + + if (NS_FAILED(rv)) return rv; + + mInputStream = bufInStream; + mOutputStream = bufOutStream; + return NS_OK; +} + +NS_METHOD +EmbedStream::OpenStream(const char *aBaseURI, const char *aContentType) +{ + NS_ENSURE_ARG_POINTER(aBaseURI); + NS_ENSURE_ARG_POINTER(aContentType); + + nsresult rv = NS_OK; + + // if we're already doing a stream then close the current one + if (mDoingStream) + CloseStream(); + + // set our state + mDoingStream = PR_TRUE; + + // initialize our streams + rv = Init(); + if (NS_FAILED(rv)) + return rv; + + // get the content area of our web browser + nsCOMPtr<nsIWebBrowser> browser; + mOwner->mWindow->GetWebBrowser(getter_AddRefs(browser)); + + // get the viewer container + nsCOMPtr<nsIContentViewerContainer> viewerContainer; + viewerContainer = do_GetInterface(browser); + + // create a new uri object + nsCOMPtr<nsIURI> uri; + nsCAutoString spec(aBaseURI); + rv = NS_NewURI(getter_AddRefs(uri), spec.get()); + + if (NS_FAILED(rv)) + return rv; + + // create a new load group + rv = NS_NewLoadGroup(getter_AddRefs(mLoadGroup), nsnull); + if (NS_FAILED(rv)) + return rv; + + // create a new input stream channel + rv = NS_NewInputStreamChannel(getter_AddRefs(mChannel), uri, + static_cast<nsIInputStream *>(this), + nsDependentCString(aContentType), + EmptyCString()); + if (NS_FAILED(rv)) + return rv; + + // set the channel's load group + rv = mChannel->SetLoadGroup(mLoadGroup); + if (NS_FAILED(rv)) + return rv; + + // find a document loader for this content type + + nsXPIDLCString docLoaderContractID; + nsCOMPtr<nsICategoryManager> catMan(do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv)); + if (NS_FAILED(rv)) + return rv; + rv = catMan->GetCategoryEntry("Gecko-Content-Viewers", aContentType, + getter_Copies(docLoaderContractID)); + if (NS_FAILED(rv)) + return rv; + + nsCOMPtr<nsIDocumentLoaderFactory> docLoaderFactory; + docLoaderFactory = do_GetService(docLoaderContractID.get(), &rv); + if (NS_FAILED(rv)) + return rv; + + // ok, create an instance of the content viewer for that command and + // mime type + nsCOMPtr<nsIContentViewer> contentViewer; + rv = docLoaderFactory->CreateInstance("view", mChannel, mLoadGroup, + aContentType, viewerContainer, + nsnull, + getter_AddRefs(mStreamListener), + getter_AddRefs(contentViewer)); + if (NS_FAILED(rv)) + return rv; + + // set the container viewer container for this content view + rv = contentViewer->SetContainer(viewerContainer); + if (NS_FAILED(rv)) + return rv; + + // embed this sucker + rv = viewerContainer->Embed(contentViewer, "view", nsnull); + if (NS_FAILED(rv)) + return rv; + + // start our request + nsCOMPtr<nsIRequest> request = do_QueryInterface(mChannel); + rv = mStreamListener->OnStartRequest(request, NULL); + if (NS_FAILED(rv)) + return rv; + + return NS_OK; +} + +NS_METHOD +EmbedStream::AppendToStream(const char *aData, gint32 aLen) +{ + nsresult rv; + + // append the data + rv = Append(aData, aLen); + if (NS_FAILED(rv)) + return rv; + + // notify our listeners + nsCOMPtr<nsIRequest> request = do_QueryInterface(mChannel); + rv = mStreamListener->OnDataAvailable(request, + NULL, + static_cast<nsIInputStream *>(this), + mOffset, /* offset */ + aLen); /* len */ + // move our counter + mOffset += aLen; + if (NS_FAILED(rv)) + return rv; + + return NS_OK; +} + +NS_METHOD +EmbedStream::CloseStream(void) +{ + nsresult rv = NS_OK; + + NS_ENSURE_STATE(mDoingStream); + mDoingStream = PR_FALSE; + + nsCOMPtr<nsIRequest> request = do_QueryInterface(mChannel, &rv); + if (NS_FAILED(rv)) + goto loser; + + rv = mStreamListener->OnStopRequest(request, NULL, NS_OK); + if (NS_FAILED(rv)) + return rv; + + loser: + mLoadGroup = nsnull; + mChannel = nsnull; + mStreamListener = nsnull; + mOffset = 0; + + return rv; +} + +NS_METHOD +EmbedStream::Append(const char *aData, PRUint32 aLen) +{ + nsresult rv = NS_OK; + PRUint32 bytesWritten = 0; + rv = mOutputStream->Write(aData, aLen, &bytesWritten); + if (NS_FAILED(rv)) + return rv; + + NS_ASSERTION(bytesWritten == aLen, + "underlying byffer couldn't handle the write"); + return rv; +} + +NS_IMETHODIMP +EmbedStream::Available(PRUint32 *_retval) +{ + return mInputStream->Available(_retval); +} + +NS_IMETHODIMP +EmbedStream::Read(char * aBuf, PRUint32 aCount, PRUint32 *_retval) +{ + return mInputStream->Read(aBuf, aCount, _retval); +} + +NS_IMETHODIMP EmbedStream::Close(void) +{ + return mInputStream->Close(); +} + +NS_IMETHODIMP +EmbedStream::ReadSegments(nsWriteSegmentFun aWriter, void * aClosure, + PRUint32 aCount, PRUint32 *_retval) +{ + char *readBuf = (char *)nsMemory::Alloc(aCount); + PRUint32 nBytes; + + if (!readBuf) + return NS_ERROR_OUT_OF_MEMORY; + + nsresult rv = mInputStream->Read(readBuf, aCount, &nBytes); + + *_retval = 0; + + if (NS_SUCCEEDED(rv)) { + PRUint32 writeCount = 0; + rv = aWriter(this, aClosure, readBuf, 0, nBytes, &writeCount); + + // XXX writeCount may be less than nBytes!! This is the wrong + // way to synthesize ReadSegments. + NS_ASSERTION(writeCount == nBytes, "data loss"); + + // errors returned from the writer end here! + rv = NS_OK; + } + + nsMemory::Free(readBuf); + + return rv; +} + +NS_IMETHODIMP +EmbedStream::IsNonBlocking(PRBool *aNonBlocking) +{ + return mInputStream->IsNonBlocking(aNonBlocking); +} diff --git a/embed/xulrunner/src/EmbedStream.h b/embed/xulrunner/src/EmbedStream.h new file mode 100644 index 000000000..bf734e134 --- /dev/null +++ b/embed/xulrunner/src/EmbedStream.h @@ -0,0 +1,79 @@ +/* + * Copyright © Christopher Blizzard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * --------------------------------------------------------------------------- + * Derived from Mozilla.org code, which had the following attributions: + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright © Christopher Blizzard. All Rights Reserved. + * Portions created by the Initial Developer are Copyright © 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Christopher Blizzard <blizzard@mozilla.org> + * --------------------------------------------------------------------------- + * + * $Id$ + */ + +#include <nsISupports.h> +#include <nsCOMPtr.h> +#include <nsIOutputStream.h> +#include <nsIInputStream.h> +#include <nsILoadGroup.h> +#include <nsIChannel.h> +#include <nsIStreamListener.h> + +class EmbedPrivate; + +class EmbedStream : public nsIInputStream +{ + public: + + EmbedStream(); + virtual ~EmbedStream(); + + void InitOwner (EmbedPrivate *aOwner); + NS_METHOD Init (void); + + NS_METHOD OpenStream (const char *aBaseURI, const char *aContentType); + NS_METHOD AppendToStream (const char *aData, PRInt32 aLen); + NS_METHOD CloseStream (void); + + NS_METHOD Append (const char *aData, PRUint32 aLen); + + // nsISupports + NS_DECL_ISUPPORTS + // nsIInputStream + NS_DECL_NSIINPUTSTREAM + + private: + nsCOMPtr<nsIOutputStream> mOutputStream; + nsCOMPtr<nsIInputStream> mInputStream; + + nsCOMPtr<nsILoadGroup> mLoadGroup; + nsCOMPtr<nsIChannel> mChannel; + nsCOMPtr<nsIStreamListener> mStreamListener; + + PRUint32 mOffset; + PRBool mDoingStream; + + EmbedPrivate *mOwner; + +}; diff --git a/embed/xulrunner/src/EmbedWindow.cpp b/embed/xulrunner/src/EmbedWindow.cpp new file mode 100644 index 000000000..15c098f28 --- /dev/null +++ b/embed/xulrunner/src/EmbedWindow.cpp @@ -0,0 +1,467 @@ +/* + * Copyright © Christopher Blizzard + * Copyright © 2006 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * --------------------------------------------------------------------------- + * Derived from Mozilla.org code, which had the following attributions: + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright © Christopher Blizzard. All Rights Reserved. + * Portions created by the Initial Developer are Copyright © 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Christopher Blizzard <blizzard@mozilla.org> + * --------------------------------------------------------------------------- + * + * $Id$ + */ + +#include <mozilla-config.h> +#include <config.h> + +#include <nsCWebBrowser.h> +#include <nsIComponentManager.h> +#include <nsComponentManagerUtils.h> +#include <nsIDocShellTreeItem.h> +#include "nsIWidget.h" + +#include "EmbedWindow.h" +#include "GeckoBrowser.h" + +#include "gecko-embed-signals.h" + +GtkWidget *EmbedWindow::sTipWindow = nsnull; + +EmbedWindow::EmbedWindow(void) +{ + mOwner = nsnull; + mVisibility = PR_FALSE; + mIsModal = PR_FALSE; +} + +EmbedWindow::~EmbedWindow(void) +{ + ExitModalEventLoop(PR_FALSE); +} + +nsresult +EmbedWindow::Init(GeckoBrowser *aOwner) +{ + // save our owner for later + mOwner = aOwner; + + // create our nsIWebBrowser object and set up some basic defaults. + mWebBrowser = do_CreateInstance(NS_WEBBROWSER_CONTRACTID); + if (!mWebBrowser) + return NS_ERROR_FAILURE; + + mWebBrowser->SetContainerWindow(static_cast<nsIWebBrowserChrome *>(this)); + + nsCOMPtr<nsIDocShellTreeItem> item = do_QueryInterface(mWebBrowser); + item->SetItemType(nsIDocShellTreeItem::typeContentWrapper); + + return NS_OK; +} + +nsresult +EmbedWindow::CreateWindow(void) +{ + nsresult rv; + GtkWidget *ownerAsWidget = GTK_WIDGET(mOwner->mOwningWidget); + + // Get the base window interface for the web browser object and + // create the window. + mBaseWindow = do_QueryInterface(mWebBrowser); + rv = mBaseWindow->InitWindow(GTK_WIDGET(mOwner->mOwningWidget), + nsnull, + 0, 0, + ownerAsWidget->allocation.width, + ownerAsWidget->allocation.height); + if (NS_FAILED(rv)) + return rv; + + rv = mBaseWindow->Create(); + if (NS_FAILED(rv)) + return rv; + + return NS_OK; +} + +void +EmbedWindow::ReleaseChildren(void) +{ + ExitModalEventLoop(PR_FALSE); + + mBaseWindow->Destroy(); + mBaseWindow = 0; + mWebBrowser = 0; +} + +// nsISupports + +NS_IMPL_ADDREF(EmbedWindow) +NS_IMPL_RELEASE(EmbedWindow) + +NS_INTERFACE_MAP_BEGIN(EmbedWindow) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebBrowserChrome) + NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome) + NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChromeFocus) + NS_INTERFACE_MAP_ENTRY(nsIEmbeddingSiteWindow) + NS_INTERFACE_MAP_ENTRY(nsITooltipListener) + NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor) +NS_INTERFACE_MAP_END + +// nsIWebBrowserChrome + +NS_IMETHODIMP +EmbedWindow::SetStatus(PRUint32 aStatusType, const PRUnichar *aStatus) +{ + switch (aStatusType) { + case STATUS_SCRIPT: + { + mJSStatus = aStatus; + g_signal_emit (mOwner->mOwningWidget, gecko_embed_signals[JS_STATUS], 0); + } + break; + case STATUS_SCRIPT_DEFAULT: + // Gee, that's nice. + break; + case STATUS_LINK: + { + mLinkMessage = aStatus; + g_signal_emit (mOwner->mOwningWidget, gecko_embed_signals[LINK_MESSAGE], 0); + } + break; + } + return NS_OK; +} + +NS_IMETHODIMP +EmbedWindow::GetWebBrowser(nsIWebBrowser **aWebBrowser) +{ + *aWebBrowser = mWebBrowser; + NS_IF_ADDREF(*aWebBrowser); + return NS_OK; +} + +NS_IMETHODIMP +EmbedWindow::SetWebBrowser(nsIWebBrowser *aWebBrowser) +{ + mWebBrowser = aWebBrowser; + return NS_OK; +} + +NS_IMETHODIMP +EmbedWindow::GetChromeFlags(PRUint32 *aChromeFlags) +{ + *aChromeFlags = mOwner->mChromeMask; + return NS_OK; +} + +NS_IMETHODIMP +EmbedWindow::SetChromeFlags(PRUint32 aChromeFlags) +{ + mOwner->SetChromeMask(aChromeFlags); + return NS_OK; +} + +NS_IMETHODIMP +EmbedWindow::DestroyBrowserWindow(void) +{ + // mark the owner as destroyed so it won't emit events anymore. + mOwner->mIsDestroyed = PR_TRUE; + + g_signal_emit (mOwner->mOwningWidget, gecko_embed_signals[DESTROY_BROWSER], 0); + return NS_OK; +} + +NS_IMETHODIMP +EmbedWindow::SizeBrowserTo(PRInt32 aCX, PRInt32 aCY) +{ + g_signal_emit (mOwner->mOwningWidget, gecko_embed_signals[SIZE_TO], 0, aCX, aCY); + + return NS_OK; +} + +NS_IMETHODIMP +EmbedWindow::ShowAsModal(void) +{ + mIsModal = PR_TRUE; + GtkWidget *toplevel; + toplevel = gtk_widget_get_toplevel(GTK_WIDGET(mOwner->mOwningWidget)); + gtk_grab_add(toplevel); + gtk_main(); + return NS_OK; +} + +NS_IMETHODIMP +EmbedWindow::IsWindowModal(PRBool *_retval) +{ + *_retval = mIsModal; + return NS_OK; +} + +NS_IMETHODIMP +EmbedWindow::ExitModalEventLoop(nsresult aStatus) +{ + if (mIsModal) { + GtkWidget *toplevel; + toplevel = gtk_widget_get_toplevel(GTK_WIDGET(mOwner->mOwningWidget)); + gtk_grab_remove(toplevel); + mIsModal = PR_FALSE; + gtk_main_quit(); + } + return NS_OK; +} + +// nsIWebBrowserChromeFocus + +NS_IMETHODIMP +EmbedWindow::FocusNextElement() +{ + GtkWidget *toplevel; + toplevel = gtk_widget_get_toplevel(GTK_WIDGET(mOwner->mOwningWidget)); + if (!GTK_WIDGET_TOPLEVEL(toplevel)) + return NS_OK; + + g_signal_emit_by_name (toplevel, "move_focus", GTK_DIR_TAB_FORWARD); + + return NS_OK; +} + +NS_IMETHODIMP +EmbedWindow::FocusPrevElement() +{ + GtkWidget *toplevel; + toplevel = gtk_widget_get_toplevel(GTK_WIDGET(mOwner->mOwningWidget)); + if (!GTK_WIDGET_TOPLEVEL(toplevel)) + return NS_OK; + + g_signal_emit_by_name (toplevel, "move_focus", GTK_DIR_TAB_BACKWARD); + + return NS_OK; +} + +// nsIEmbeddingSiteWindow + +NS_IMETHODIMP +EmbedWindow::SetDimensions(PRUint32 aFlags, PRInt32 aX, PRInt32 aY, + PRInt32 aCX, PRInt32 aCY) +{ + if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION && + (aFlags & (nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_INNER | + nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_OUTER))) { + return mBaseWindow->SetPositionAndSize(aX, aY, aCX, aCY, PR_TRUE); + } + else if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION) { + return mBaseWindow->SetPosition(aX, aY); + } + else if (aFlags & (nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_INNER | + nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_OUTER)) { + return mBaseWindow->SetSize(aCX, aCY, PR_TRUE); + } + return NS_ERROR_INVALID_ARG; +} + +NS_IMETHODIMP +EmbedWindow::GetDimensions(PRUint32 aFlags, PRInt32 *aX, + PRInt32 *aY, PRInt32 *aCX, PRInt32 *aCY) +{ + if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION && + (aFlags & (nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_INNER | + nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_OUTER))) { + return mBaseWindow->GetPositionAndSize(aX, aY, aCX, aCY); + } + else if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION) { + return mBaseWindow->GetPosition(aX, aY); + } + else if (aFlags & (nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_INNER | + nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_OUTER)) { + return mBaseWindow->GetSize(aCX, aCY); + } + return NS_ERROR_INVALID_ARG; +} + +NS_IMETHODIMP +EmbedWindow::SetFocus(void) +{ + // XXX might have to do more here. + return mBaseWindow->SetFocus(); +} + +NS_IMETHODIMP +EmbedWindow::GetTitle(PRUnichar **aTitle) +{ + *aTitle = NS_StringCloneData(mTitle); + return NS_OK; +} + +NS_IMETHODIMP +EmbedWindow::SetTitle(const PRUnichar *aTitle) +{ + mTitle = aTitle; + g_signal_emit (mOwner->mOwningWidget, gecko_embed_signals[TITLE], 0); + + return NS_OK; +} + +NS_IMETHODIMP +EmbedWindow::GetSiteWindow(void **aSiteWindow) +{ + GtkWidget *ownerAsWidget (GTK_WIDGET(mOwner->mOwningWidget)); + *aSiteWindow = static_cast<void *>(ownerAsWidget); + return NS_OK; +} + +NS_IMETHODIMP +EmbedWindow::GetVisibility(PRBool *aVisibility) +{ + // Work around the problem that sometimes the window + // is already visible even though mVisibility isn't true + // yet. + *aVisibility = mVisibility || + (!mOwner->mIsChrome && + mOwner->mOwningWidget && + GTK_WIDGET_MAPPED(mOwner->mOwningWidget)); + return NS_OK; +} + +NS_IMETHODIMP +EmbedWindow::SetVisibility(PRBool aVisibility) +{ + // We always set the visibility so that if it's chrome and we finish + // the load we know that we have to show the window. + mVisibility = aVisibility; + + // if this is a chrome window and the chrome hasn't finished loading + // yet then don't show the window yet. + if (mOwner->mIsChrome && !mOwner->mChromeLoaded) + return NS_OK; + + g_signal_emit (mOwner->mOwningWidget, gecko_embed_signals[VISIBILITY], 0, + aVisibility); + return NS_OK; +} + +// nsITooltipListener + +static gboolean +tooltips_paint_window (GtkWidget *window) +{ + // draw tooltip style border around the text + gtk_paint_flat_box (window->style, window->window, + GTK_STATE_NORMAL, GTK_SHADOW_OUT, + NULL, window, "tooltip", + 0, 0, + window->allocation.width, window->allocation.height); + + return FALSE; +} + +NS_IMETHODIMP +EmbedWindow::OnShowTooltip(PRInt32 aXCoords, PRInt32 aYCoords, + const PRUnichar *aTipText) +{ + nsEmbedCString tipText; + + NS_UTF16ToCString(nsEmbedString(aTipText), + NS_CSTRING_ENCODING_UTF8, tipText); + + if (sTipWindow) + gtk_widget_destroy(sTipWindow); + + // get the root origin for this content window + nsCOMPtr<nsIWidget> mainWidget; + mBaseWindow->GetMainWidget(getter_AddRefs(mainWidget)); + GdkWindow *window; + window = static_cast<GdkWindow *> + (mainWidget->GetNativeData(NS_NATIVE_WINDOW)); + gint root_x, root_y; + gdk_window_get_origin(window, &root_x, &root_y); + + // XXX work around until I can get pink to figure out why + // tooltips vanish if they show up right at the origin of the + // cursor. + root_y += 10; + + sTipWindow = gtk_window_new(GTK_WINDOW_POPUP); + gtk_widget_set_app_paintable(sTipWindow, TRUE); + gtk_window_set_policy(GTK_WINDOW(sTipWindow), FALSE, FALSE, TRUE); + // needed to get colors + fonts etc correctly + gtk_widget_set_name(sTipWindow, "gtk-tooltips"); + + // set up the popup window as a transient of the widget. + GtkWidget *toplevel_window; + toplevel_window = gtk_widget_get_toplevel(GTK_WIDGET(mOwner->mOwningWidget)); + if (!GTK_WINDOW(toplevel_window)) { + NS_ERROR("no gtk window in hierarchy!\n"); + return NS_ERROR_FAILURE; + } + gtk_window_set_transient_for(GTK_WINDOW(sTipWindow), + GTK_WINDOW(toplevel_window)); + + // realize the widget + gtk_widget_realize(sTipWindow); + + g_signal_connect (G_OBJECT(sTipWindow), "expose-event", + G_CALLBACK(tooltips_paint_window), NULL); + + // set up the label for the tooltip + GtkWidget *label = gtk_label_new(tipText.get()); + // wrap automatically + gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); + gtk_container_add(GTK_CONTAINER(sTipWindow), label); + gtk_container_set_border_width(GTK_CONTAINER(sTipWindow), 4); + // set the coords for the widget + gtk_widget_set_uposition(sTipWindow, aXCoords + root_x, + aYCoords + root_y); + + // and show it. + gtk_widget_show_all(sTipWindow); + + return NS_OK; +} + +NS_IMETHODIMP +EmbedWindow::OnHideTooltip(void) +{ + if (sTipWindow) + gtk_widget_destroy(sTipWindow); + sTipWindow = NULL; + return NS_OK; +} + +// nsIInterfaceRequestor + +NS_IMETHODIMP +EmbedWindow::GetInterface(const nsIID &aIID, void** aInstancePtr) +{ + nsresult rv; + + rv = QueryInterface(aIID, aInstancePtr); + + // pass it up to the web browser object + if (NS_FAILED(rv) || !*aInstancePtr) { + nsCOMPtr<nsIInterfaceRequestor> ir = do_QueryInterface(mWebBrowser); + return ir->GetInterface(aIID, aInstancePtr); + } + + return rv; +} diff --git a/embed/xulrunner/src/EmbedWindow.h b/embed/xulrunner/src/EmbedWindow.h new file mode 100644 index 000000000..e03164d7e --- /dev/null +++ b/embed/xulrunner/src/EmbedWindow.h @@ -0,0 +1,97 @@ +/* + * Copyright © Christopher Blizzard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * --------------------------------------------------------------------------- + * Derived from Mozilla.org code, which had the following attributions: + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright © Christopher Blizzard. All Rights Reserved. + * Portions created by the Initial Developer are Copyright © 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Christopher Blizzard <blizzard@mozilla.org> + * --------------------------------------------------------------------------- + * + * $Id$ + */ + +#ifndef __EmbedWindow_h +#define __EmbedWindow_h + +#include <nsEmbedString.h> +#include <nsIWebBrowserChrome.h> +#include <nsIWebBrowserChromeFocus.h> +#include <nsIEmbeddingSiteWindow.h> +#include <nsITooltipListener.h> +#include <nsISupports.h> +#include <nsIWebBrowser.h> +#include <nsIBaseWindow.h> +#include <nsIInterfaceRequestor.h> +#include <nsCOMPtr.h> + +#include <gtk/gtk.h> + +class GeckoBrowser; + +class EmbedWindow : public nsIWebBrowserChrome, + public nsIWebBrowserChromeFocus, + public nsIEmbeddingSiteWindow, + public nsITooltipListener, + public nsIInterfaceRequestor +{ + + public: + + EmbedWindow(); + virtual ~EmbedWindow(); + + nsresult Init (GeckoBrowser *aOwner); + nsresult CreateWindow (void); + void ReleaseChildren (void); + + NS_DECL_ISUPPORTS + + NS_DECL_NSIWEBBROWSERCHROME + + NS_DECL_NSIWEBBROWSERCHROMEFOCUS + + NS_DECL_NSIEMBEDDINGSITEWINDOW + + NS_DECL_NSITOOLTIPLISTENER + + NS_DECL_NSIINTERFACEREQUESTOR + + nsEmbedString mTitle; + nsEmbedString mJSStatus; + nsEmbedString mLinkMessage; + + nsCOMPtr<nsIBaseWindow> mBaseWindow; // [OWNER] + +private: + + GeckoBrowser *mOwner; + nsCOMPtr<nsIWebBrowser> mWebBrowser; // [OWNER] + static GtkWidget *sTipWindow; + PRBool mVisibility; + PRBool mIsModal; + +}; + +#endif /* __EmbedWindow_h */ diff --git a/embed/xulrunner/src/EmbedWindowCreator.cpp b/embed/xulrunner/src/EmbedWindowCreator.cpp new file mode 100644 index 000000000..1c05add95 --- /dev/null +++ b/embed/xulrunner/src/EmbedWindowCreator.cpp @@ -0,0 +1,108 @@ +/* + * Copyright © Christopher Blizzard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * --------------------------------------------------------------------------- + * Derived from Mozilla.org code, which had the following attributions: + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright © Christopher Blizzard. All Rights Reserved. + * Portions created by the Initial Developer are Copyright © 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Christopher Blizzard <blizzard@mozilla.org> + * --------------------------------------------------------------------------- + * + * $Id$ + */ + +#include <mozilla-config.h> +#include "config.h" + +#include "EmbedWindowCreator.h" +#include "GeckoBrowser.h" +#include "GeckoSingle.h" +#include "EmbedWindow.h" + +#include "gecko-embed-private.h" +#include "gecko-embed-single-private.h" +#include "gecko-embed-signals.h" + +EmbedWindowCreator::EmbedWindowCreator(void) +{ +} + +EmbedWindowCreator::~EmbedWindowCreator() +{ +} + +NS_IMPL_ISUPPORTS1(EmbedWindowCreator, nsIWindowCreator) + +NS_IMETHODIMP +EmbedWindowCreator::CreateChromeWindow(nsIWebBrowserChrome *aParent, + PRUint32 aChromeFlags, + nsIWebBrowserChrome **_retval) +{ + NS_ENSURE_ARG_POINTER(_retval); + + GeckoEmbed *newEmbed = nsnull; + + // No parent? Ask via the singleton object instead. + if (!aParent) { + gecko_embed_single_create_window(&newEmbed, + (guint)aChromeFlags); + } + else { + // Find the GeckoBrowser object for this web browser chrome object. + GeckoBrowser *browser = GeckoSingle::FindPrivateForBrowser(aParent); + + if (!browser) + return NS_ERROR_FAILURE; + + g_signal_emit (browser->mOwningWidget, gecko_embed_signals[NEW_WINDOW], 0, + &newEmbed, (guint) aChromeFlags); + + } + + // check to make sure that we made a new window + if (!newEmbed) + return NS_ERROR_FAILURE; + + // The window _must_ be realized before we pass it back to the + // function that created it. Functions that create new windows + // will do things like GetDocShell() and the widget has to be + // realized before that can happen. + gtk_widget_realize(GTK_WIDGET(newEmbed)); + + GeckoBrowser *newGeckoBrowser = gecko_embed_get_GeckoBrowser (newEmbed); + + // set the chrome flag on the new window if it's a chrome open + if (aChromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME) + newGeckoBrowser->mIsChrome = PR_TRUE; + + *_retval = static_cast<nsIWebBrowserChrome *> + ((newGeckoBrowser->mWindow)); + + if (*_retval) { + NS_ADDREF(*_retval); + return NS_OK; + } + + return NS_ERROR_FAILURE; +} diff --git a/embed/xulrunner/src/EmbedWindowCreator.h b/embed/xulrunner/src/EmbedWindowCreator.h new file mode 100644 index 000000000..9c4e9daa5 --- /dev/null +++ b/embed/xulrunner/src/EmbedWindowCreator.h @@ -0,0 +1,51 @@ +/* + * Copyright © Christopher Blizzard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * --------------------------------------------------------------------------- + * Derived from Mozilla.org code, which had the following attributions: + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright © Christopher Blizzard. All Rights Reserved. + * Portions created by the Initial Developer are Copyright © 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Christopher Blizzard <blizzard@mozilla.org> + * --------------------------------------------------------------------------- + * + * $Id$ + */ + +#ifndef __EmbedWindowCreator_h +#define __EmbedWindowCreator_h + +#include <nsIWindowCreator.h> + +class EmbedWindowCreator : public nsIWindowCreator +{ + public: + EmbedWindowCreator(); + virtual ~EmbedWindowCreator(); + + NS_DECL_ISUPPORTS + NS_DECL_NSIWINDOWCREATOR + +}; + +#endif /* __EmbedWindowCreator_h */ diff --git a/embed/xulrunner/src/GeckoBrowser.cpp b/embed/xulrunner/src/GeckoBrowser.cpp new file mode 100644 index 000000000..5a91a98bf --- /dev/null +++ b/embed/xulrunner/src/GeckoBrowser.cpp @@ -0,0 +1,676 @@ +/* + * Copyright © Christopher Blizzard + * Copyright © 2006 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * --------------------------------------------------------------------------- + * Derived from Mozilla.org code, which had the following attributions: + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright © Christopher Blizzard. All Rights Reserved. + * Portions created by the Initial Developer are Copyright © 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Christopher Blizzard <blizzard@mozilla.org> + * --------------------------------------------------------------------------- + * + * $Id$ + */ + +#include <mozilla-config.h> +#include "config.h" + +#include "nsIDocShell.h" +#include "nsIWebProgress.h" +#include "nsIWebBrowserStream.h" +#include "nsIWebBrowserFocus.h" +#include "nsIWidget.h" +#include <stdlib.h> + +// for NS_APPSHELL_CID +#include "nsWidgetsCID.h" + +// for do_GetInterface +#include "nsIInterfaceRequestor.h" +// for do_CreateInstance +#include "nsIComponentManager.h" + +// for initializing our window watcher service +#include "nsIWindowWatcher.h" + +#include "nsILocalFile.h" +#include "nsEmbedAPI.h" + +// all of the crap that we need for event listeners +// and when chrome windows finish loading +#include "nsIDOMWindow.h" +#include "nsPIDOMWindow.h" +#include "nsIDOMWindowInternal.h" + +// For seting scrollbar visibilty +#include <nsIDOMBarProp.h> + +// for the focus hacking we need to do +#include "nsIFocusController.h" + +// for profiles +#define STANDALONE_PROFILEDIRSERVICE +#include "nsProfileDirServiceProvider.h" + +// app component registration +#include "nsIGenericFactory.h" +#include "nsIComponentRegistrar.h" + +// all of our local includes +#include "GeckoBrowser.h" +#include "EmbedWindow.h" +#include "EmbedProgress.h" +#include "EmbedContentListener.h" +#include "EmbedEventListener.h" +#include "EmbedWindowCreator.h" + +#ifdef MOZ_ACCESSIBILITY_ATK +#include "nsIAccessibilityService.h" +#include "nsIAccessible.h" +#include "nsIDOMDocument.h" +#endif + +#include "GeckoSingle.h" + +GeckoBrowser::GeckoBrowser(void) + : mOwningWidget(nsnull) + , mWindow(nsnull) + , mProgress(nsnull) + , mContentListener(nsnull) + , mEventListener(nsnull) + , mChromeMask(nsIWebBrowserChrome::CHROME_ALL) + , mIsChrome(PR_FALSE) + , mChromeLoaded(PR_FALSE) + , mListenersAttached(PR_FALSE) + , mMozWindowWidget(nsnull) + , mIsDestroyed(PR_FALSE) +{ + GeckoSingle::AddBrowser(this); +} + +GeckoBrowser::~GeckoBrowser() +{ + GeckoSingle::RemoveBrowser(this); +} + +nsresult +GeckoBrowser::Init(GeckoEmbed *aOwningWidget) +{ + // are we being re-initialized? + if (mOwningWidget) + return NS_OK; + + // hang on with a reference to the owning widget + mOwningWidget = aOwningWidget; + + // Create our embed window, and create an owning reference to it and + // initialize it. It is assumed that this window will be destroyed + // when we go out of scope. + mWindow = new EmbedWindow(); + mWindowGuard = static_cast<nsIWebBrowserChrome *>(mWindow); + mWindow->Init(this); + + // Create our progress listener object, make an owning reference, + // and initialize it. It is assumed that this progress listener + // will be destroyed when we go out of scope. + mProgress = new EmbedProgress(); + mProgressGuard = static_cast<nsIWebProgressListener *> + (mProgress); + mProgress->Init(this); + + // Create our content listener object, initialize it and attach it. + // It is assumed that this will be destroyed when we go out of + // scope. + mContentListener = new EmbedContentListener(); + mContentListenerGuard = static_cast<nsISupports*>(static_cast<nsIURIContentListener*>(mContentListener)); + mContentListener->Init(this); + + // Create our key listener object and initialize it. It is assumed + // that this will be destroyed before we go out of scope. + mEventListener = new EmbedEventListener(this); + mEventListenerGuard = + static_cast<nsISupports *>(static_cast<nsIDOMKeyListener *> + (mEventListener)); + + return NS_OK; +} + +nsresult +GeckoBrowser::Realize(PRBool *aAlreadyRealized) +{ + + *aAlreadyRealized = PR_FALSE; + + // Have we ever been initialized before? If so then just reparent + // from the offscreen window. + if (mMozWindowWidget) { + gtk_widget_reparent(mMozWindowWidget, GTK_WIDGET(mOwningWidget)); + *aAlreadyRealized = PR_TRUE; + return NS_OK; + } + + // Get the nsIWebBrowser object for our embedded window. + nsCOMPtr<nsIWebBrowser> webBrowser; + mWindow->GetWebBrowser(getter_AddRefs(webBrowser)); + + // get a handle on the navigation object + mNavigation = do_QueryInterface(webBrowser); + + // Create our session history object and tell the navigation object + // to use it. We need to do this before we create the web browser + // window. + mSessionHistory = do_CreateInstance(NS_SHISTORY_CONTRACTID); + mNavigation->SetSessionHistory(mSessionHistory); + + // create the window + mWindow->CreateWindow(); + + // bind the progress listener to the browser object + nsCOMPtr<nsISupportsWeakReference> supportsWeak; + supportsWeak = do_QueryInterface(mProgressGuard); + nsCOMPtr<nsIWeakReference> weakRef; + supportsWeak->GetWeakReference(getter_AddRefs(weakRef)); + webBrowser->AddWebBrowserListener(weakRef, + NS_GET_IID (nsIWebProgressListener)); + + // set ourselves as the parent uri content listener + nsCOMPtr<nsIURIContentListener> uriListener; + uriListener = do_QueryInterface(mContentListenerGuard); + webBrowser->SetParentURIContentListener(uriListener); + + // save the window id of the newly created window + nsCOMPtr<nsIWidget> mozWidget; + mWindow->mBaseWindow->GetMainWidget(getter_AddRefs(mozWidget)); + // get the native drawing area + GdkWindow *tmp_window = + static_cast<GdkWindow *> + (mozWidget->GetNativeData(NS_NATIVE_WINDOW)); + // and, thanks to superwin we actually need the parent of that. + // FIXME is this true on gtk2 widget? + tmp_window = gdk_window_get_parent(tmp_window); + // save the widget ID - it should be the mozarea of the window. + gpointer data = nsnull; + gdk_window_get_user_data(tmp_window, &data); + mMozWindowWidget = static_cast<GtkWidget *>(data); + + // Apply the current chrome mask + ApplyChromeMask(); + + return NS_OK; +} + +void +GeckoBrowser::Unrealize(void) +{ + // reparent to our offscreen window + GeckoSingle::ReparentToOffscreen(mMozWindowWidget); +} + +void +GeckoBrowser::Show(void) +{ + // Get the nsIWebBrowser object for our embedded window. + nsCOMPtr<nsIWebBrowser> webBrowser; + mWindow->GetWebBrowser (getter_AddRefs (webBrowser)); + + // and set the visibility on the thing + nsCOMPtr<nsIBaseWindow> baseWindow (do_QueryInterface (webBrowser)); + baseWindow->SetVisibility(PR_TRUE); +} + +void +GeckoBrowser::Hide(void) +{ + // Get the nsIWebBrowser object for our embedded window. + nsCOMPtr<nsIWebBrowser> webBrowser; + mWindow->GetWebBrowser (getter_AddRefs (webBrowser)); + + // and set the visibility on the thing + nsCOMPtr<nsIBaseWindow> baseWindow (do_QueryInterface (webBrowser)); + baseWindow->SetVisibility (PR_FALSE); +} + +void +GeckoBrowser::Resize(PRUint32 aWidth, PRUint32 aHeight) +{ + mWindow->SetDimensions(nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION | + nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_INNER, + 0, 0, aWidth, aHeight); +} + +void +GeckoBrowser::Destroy(void) +{ + // This flag might have been set from + // EmbedWindow::DestroyBrowserWindow() as well if someone used a + // window.close() or something or some other script action to close + // the window. No harm setting it again. + mIsDestroyed = PR_TRUE; + + // Get the nsIWebBrowser object for our embedded window. + nsCOMPtr<nsIWebBrowser> webBrowser; + mWindow->GetWebBrowser(getter_AddRefs(webBrowser)); + + // Release our progress listener + nsCOMPtr<nsISupportsWeakReference> supportsWeak + (do_QueryInterface(mProgressGuard)); + nsCOMPtr<nsIWeakReference> weakRef; + supportsWeak->GetWeakReference(getter_AddRefs(weakRef)); + webBrowser->RemoveWebBrowserListener(weakRef, + NS_GET_IID (nsIWebProgressListener)); + weakRef = nsnull; + supportsWeak = nsnull; + + // Release our content listener + webBrowser->SetParentURIContentListener(nsnull); + mContentListenerGuard = nsnull; + mContentListener = nsnull; + + // Now that we have removed the listener, release our progress + // object + mProgressGuard = nsnull; + mProgress = nsnull; + + // detach our event listeners and release the event receiver + DetachListeners(); + + mEventTarget = nsnull; + + // destroy our child window + mWindow->ReleaseChildren(); + + // release navigation + mNavigation = nsnull; + + // release session history + mSessionHistory = nsnull; + + mOwningWidget = nsnull; + + mMozWindowWidget = 0; +} + +void +GeckoBrowser::Reload(PRUint32 reloadFlags) +{ + /* Use the session history if it is available, this + * allows framesets to reload correctly */ + nsCOMPtr<nsIWebNavigation> wn (do_QueryInterface(mSessionHistory)); + + if (!wn) + wn = mNavigation; + + NS_ENSURE_TRUE (wn, ); + + wn->Reload(reloadFlags); +} + +void +GeckoBrowser::ApplyChromeMask() +{ + if (mWindow) { + nsCOMPtr<nsIWebBrowser> webBrowser; + mWindow->GetWebBrowser(getter_AddRefs(webBrowser)); + + nsCOMPtr<nsIDOMWindow> domWindow; + webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow)); + if (domWindow) { + + nsCOMPtr<nsIDOMBarProp> scrollbars; + domWindow->GetScrollbars(getter_AddRefs(scrollbars)); + if (scrollbars) { + + scrollbars->SetVisible + (mChromeMask & nsIWebBrowserChrome::CHROME_SCROLLBARS ? + PR_TRUE : PR_FALSE); + } + } + } +} + + +void +GeckoBrowser::SetChromeMask(PRUint32 aChromeMask) +{ + mChromeMask = aChromeMask; + + ApplyChromeMask(); +} + +void +GeckoBrowser::SetURI(const char *aURI) +{ + mURI = aURI; +} + +void +GeckoBrowser::LoadCurrentURI(void) +{ + if (mURI.Length()) { + nsCOMPtr<nsPIDOMWindow> piWin; + GetPIDOMWindow(getter_AddRefs(piWin)); + nsAutoPopupStatePusher popupStatePusher(piWin, openAllowed); + + nsEmbedString uri; + NS_CStringToUTF16(mURI, NS_CSTRING_ENCODING_UTF8, uri); + mNavigation->LoadURI(uri.get(), // URI string + nsIWebNavigation::LOAD_FLAGS_NONE, // Load flags + nsnull, // Referring URI + nsnull, // Post data + nsnull); // extra headers + } +} + +#if 0 +nsresult +GeckoBrowser::OpenStream(const char *aBaseURI, const char *aContentType) +{ + nsCOMPtr<nsIWebBrowser> webBrowser; + mWindow->GetWebBrowser(getter_AddRefs(webBrowser)); + + nsCOMPtr<nsIWebBrowserStream> wbStream = do_QueryInterface(webBrowser); + if (!wbStream) return NS_ERROR_FAILURE; + + return wbStream->OpenStream(aBaseURI, aContentType); +} + +nsresult +GeckoBrowser::AppendToStream(const char *aData, PRInt32 aLen) +{ + // Attach listeners to this document since in some cases we don't + // get updates for content added this way. + ContentStateChange(); + + nsCOMPtr<nsIWebBrowser> webBrowser; + mWindow->GetWebBrowser(getter_AddRefs(webBrowser)); + + nsCOMPtr<nsIWebBrowserStream> wbStream = do_QueryInterface(webBrowser); + if (!wbStream) return NS_ERROR_FAILURE; + + return wbStream->AppendToStream(aData, aLen); +} + +nsresult +GeckoBrowser::CloseStream(void) +{ + nsCOMPtr<nsIWebBrowser> webBrowser; + mWindow->GetWebBrowser(getter_AddRefs(webBrowser)); + + nsCOMPtr<nsIWebBrowserStream> wbStream = do_QueryInterface(webBrowser); + if (!wbStream) return NS_ERROR_FAILURE; + + return wbStream->CloseStream(); +} +#endif + +void +GeckoBrowser::ContentStateChange(void) +{ + + // we don't attach listeners to chrome + if (mListenersAttached && !mIsChrome) + return; + + GetListener(); + + if (!mEventTarget) + return; + + AttachListeners(); + +} + +void +GeckoBrowser::ContentFinishedLoading(void) +{ + if (mIsChrome) { + // We're done loading. + mChromeLoaded = PR_TRUE; + + // get the web browser + nsCOMPtr<nsIWebBrowser> webBrowser; + mWindow->GetWebBrowser(getter_AddRefs(webBrowser)); + + // get the content DOM window for that web browser + nsCOMPtr<nsIDOMWindow> domWindow; + webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow)); + if (!domWindow) { + NS_WARNING("no dom window in content finished loading\n"); + return; + } + + // resize the content + domWindow->SizeToContent(); + + // and since we're done loading show the window, assuming that the + // visibility flag has been set. + PRBool visibility; + mWindow->GetVisibility(&visibility); + if (visibility) + mWindow->SetVisibility(PR_TRUE); + } +} + +void +GeckoBrowser::ChildFocusIn(void) +{ + if (mIsDestroyed) + return; + + nsresult rv; + nsCOMPtr<nsIWebBrowser> webBrowser; + rv = mWindow->GetWebBrowser(getter_AddRefs(webBrowser)); + if (NS_FAILED(rv)) + return; + + nsCOMPtr<nsIWebBrowserFocus> webBrowserFocus(do_QueryInterface(webBrowser)); + if (!webBrowserFocus) + return; + + webBrowserFocus->Activate(); +} + +void +GeckoBrowser::ChildFocusOut(void) +{ + if (mIsDestroyed) + return; + + nsresult rv; + nsCOMPtr<nsIWebBrowser> webBrowser; + rv = mWindow->GetWebBrowser(getter_AddRefs(webBrowser)); + if (NS_FAILED(rv)) + return; + + nsCOMPtr<nsIWebBrowserFocus> webBrowserFocus(do_QueryInterface(webBrowser)); + if (!webBrowserFocus) + return; + + webBrowserFocus->Deactivate(); +} + +// Get the event listener for the chrome event handler. + +void +GeckoBrowser::GetListener(void) +{ + if (mEventTarget) + return; + + nsCOMPtr<nsPIDOMWindow> piWin; + GetPIDOMWindow(getter_AddRefs(piWin)); + + if (!piWin) + return; + + mEventTarget = do_QueryInterface(piWin->GetChromeEventHandler()); +} + +// attach key and mouse event listeners + +void +GeckoBrowser::AttachListeners(void) +{ + if (!mEventTarget || mListenersAttached) + return; + + nsIDOMEventListener *eventListener = + static_cast<nsIDOMEventListener *> + (static_cast<nsIDOMKeyListener *>(mEventListener)); + + // add the key listener + nsresult rv; + rv = mEventTarget->AddEventListenerByIID(eventListener, + NS_GET_IID(nsIDOMKeyListener)); + if (NS_FAILED(rv)) { + NS_WARNING("Failed to add key listener\n"); + return; + } + + rv = mEventTarget->AddEventListenerByIID(eventListener, + NS_GET_IID(nsIDOMMouseListener)); + if (NS_FAILED(rv)) { + NS_WARNING("Failed to add mouse listener\n"); + return; + } + + rv = mEventTarget->AddEventListenerByIID(eventListener, + NS_GET_IID(nsIDOMUIListener)); + if (NS_FAILED(rv)) { + NS_WARNING("Failed to add UI listener\n"); + return; + } + + rv = mEventTarget->AddEventListenerByIID(eventListener, + NS_GET_IID(nsIDOMContextMenuListener)); + if (NS_FAILED(rv)) { + NS_WARNING("Failed to add context menu listener\n"); + return; + } + + // ok, all set. + mListenersAttached = PR_TRUE; +} + +void +GeckoBrowser::DetachListeners(void) +{ + if (!mListenersAttached || !mEventTarget) + return; + + nsIDOMEventListener *eventListener = + static_cast<nsIDOMEventListener *> + (static_cast<nsIDOMKeyListener *>(mEventListener)); + + nsresult rv; + rv = mEventTarget->RemoveEventListenerByIID(eventListener, + NS_GET_IID(nsIDOMKeyListener)); + if (NS_FAILED(rv)) { + NS_WARNING("Failed to remove key listener\n"); + return; + } + + rv = + mEventTarget->RemoveEventListenerByIID(eventListener, + NS_GET_IID(nsIDOMMouseListener)); + if (NS_FAILED(rv)) { + NS_WARNING("Failed to remove mouse listener\n"); + return; + } + + rv = mEventTarget->RemoveEventListenerByIID(eventListener, + NS_GET_IID(nsIDOMUIListener)); + if (NS_FAILED(rv)) { + NS_WARNING("Failed to remove UI listener\n"); + return; + } + + rv = mEventTarget->RemoveEventListenerByIID(eventListener, + NS_GET_IID(nsIDOMContextMenuListener)); + if (NS_FAILED(rv)) { + NS_WARNING("Failed to remove context menu listener\n"); + return; + } + + mListenersAttached = PR_FALSE; +} + +nsresult +GeckoBrowser::GetPIDOMWindow(nsPIDOMWindow **aPIWin) +{ + *aPIWin = nsnull; + + // get the web browser + nsCOMPtr<nsIWebBrowser> webBrowser; + mWindow->GetWebBrowser(getter_AddRefs(webBrowser)); + + // get the content DOM window for that web browser + nsCOMPtr<nsIDOMWindow> domWindow; + webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow)); + if (!domWindow) + return NS_ERROR_FAILURE; + + // get the private DOM window + nsCOMPtr<nsPIDOMWindow> domWindowPrivate = do_QueryInterface(domWindow); + // and the root window for that DOM window + *aPIWin = domWindowPrivate->GetPrivateRoot(); + + if (*aPIWin) { + NS_ADDREF(*aPIWin); + return NS_OK; + } + + return NS_ERROR_FAILURE; +} + +#ifdef MOZ_ACCESSIBILITY_ATK +// FIXME does this REALLY work with frames? +void * +GeckoBrowser::GetAtkObjectForCurrentDocument() +{ + if (!mNavigation) + return nsnull; + + nsCOMPtr<nsIAccessibilityService> accService = + do_GetService("@mozilla.org/accessibilityService;1"); + if (accService) { + //get current document + nsCOMPtr<nsIDOMDocument> domDoc; + mNavigation->GetDocument(getter_AddRefs(domDoc)); + NS_ENSURE_TRUE(domDoc, nsnull); + + nsCOMPtr<nsIDOMNode> domNode(do_QueryInterface(domDoc)); + NS_ENSURE_TRUE(domNode, nsnull); + + nsCOMPtr<nsIAccessible> acc; + accService->GetAccessibleFor(domNode, getter_AddRefs(acc)); + NS_ENSURE_TRUE(acc, nsnull); + + void *atkObj = nsnull; + if (NS_SUCCEEDED(acc->GetNativeInterface(&atkObj))) + return atkObj; + } + return nsnull; +} +#endif /* MOZ_ACCESSIBILITY_ATK */ diff --git a/embed/xulrunner/src/GeckoBrowser.h b/embed/xulrunner/src/GeckoBrowser.h new file mode 100644 index 000000000..0d7a86af3 --- /dev/null +++ b/embed/xulrunner/src/GeckoBrowser.h @@ -0,0 +1,159 @@ +/* + * Copyright © Christopher Blizzard + * Copyright © 2006 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * --------------------------------------------------------------------------- + * Derived from Mozilla.org code, which had the following attributions: + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright © Christopher Blizzard. All Rights Reserved. + * Portions created by the Initial Developer are Copyright © 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Christopher Blizzard <blizzard@mozilla.org> + * --------------------------------------------------------------------------- + * + * $Id$ + */ + +#ifndef __GeckoBrowser_h +#define __GeckoBrowser_h + +#include <nsCOMPtr.h> +#include <nsEmbedString.h> +#include <nsIWebNavigation.h> +#include <nsISHistory.h> +// for our one function that gets the GeckoBrowser via the chrome +// object. +#include <nsIWebBrowserChrome.h> +#include <nsIAppShell.h> +#include <nsPIDOMEventTarget.h> +// app component registration +#include <nsIGenericFactory.h> +#include <nsIComponentRegistrar.h> + +#include "gecko-embed.h" + +class EmbedProfile; +class EmbedProgress; +class EmbedWindow; +class EmbedContentListener; +class EmbedEventListener; + +class nsPIDOMWindow; +class nsIDirectoryServiceProvider; +class nsProfileDirServiceProvider; + +class GeckoBrowser { + + public: + + GeckoBrowser(); + ~GeckoBrowser(); + + nsresult Init (GeckoEmbed *aOwningWidget); + nsresult Realize (PRBool *aAlreadRealized); + void Unrealize (void); + void Show (void); + void Hide (void); + void Resize (PRUint32 aWidth, PRUint32 aHeight); + void Destroy (void); + void SetURI (const char *aURI); + void LoadCurrentURI (void); + void Reload (PRUint32 reloadFlags); + + void SetChromeMask (PRUint32 chromeMask); + void ApplyChromeMask (); + + nsresult OpenStream (const char *aBaseURI, const char *aContentType); + nsresult AppendToStream (const char *aData, PRInt32 aLen); + nsresult CloseStream (void); + + // This is an upcall that will come from the progress listener + // whenever there is a content state change. We need this so we can + // attach event listeners. + void ContentStateChange (void); + + // This is an upcall from the progress listener when content is + // finished loading. We have this so that if it's chrome content + // that we can size to content properly and show ourselves if + // visibility is set. + void ContentFinishedLoading(void); + + // these let the widget code know when the toplevel window gets and + // looses focus. + void TopLevelFocusIn (void); + void TopLevelFocusOut(void); + + // these are when the widget itself gets focus in and focus out + // events + void ChildFocusIn (void); + void ChildFocusOut(void); + +#ifdef MOZ_ACCESSIBILITY_ATK + void *GetAtkObjectForCurrentDocument(); +#endif + + GeckoEmbed *mOwningWidget; + + // all of the objects that we own + EmbedWindow *mWindow; + nsCOMPtr<nsISupports> mWindowGuard; + EmbedProgress *mProgress; + nsCOMPtr<nsISupports> mProgressGuard; + EmbedContentListener *mContentListener; + nsCOMPtr<nsISupports> mContentListenerGuard; + EmbedEventListener *mEventListener; + nsCOMPtr<nsISupports> mEventListenerGuard; + + nsCOMPtr<nsIWebNavigation> mNavigation; + nsCOMPtr<nsISHistory> mSessionHistory; + + // our event receiver + nsCOMPtr<nsPIDOMEventTarget> mEventTarget; + + // the currently loaded uri + nsEmbedCString mURI; + + // chrome mask + PRUint32 mChromeMask; + // is this a chrome window? + PRBool mIsChrome; + // has the chrome finished loading? + PRBool mChromeLoaded; + // saved window ID for reparenting later + GtkWidget *mMozWindowWidget; + // has someone called Destroy() on us? + PRBool mIsDestroyed; + + private: + + // is the chrome listener attached yet? + PRBool mListenersAttached; + + void GetListener (void); + void AttachListeners (void); + void DetachListeners (void); + + // this will get the PIDOMWindow for this widget + nsresult GetPIDOMWindow (nsPIDOMWindow **aPIWin); +}; + +#endif /* __GeckoBrowser_h */ diff --git a/embed/xulrunner/src/GeckoPromptService.cpp b/embed/xulrunner/src/GeckoPromptService.cpp new file mode 100644 index 000000000..c9c5b03c2 --- /dev/null +++ b/embed/xulrunner/src/GeckoPromptService.cpp @@ -0,0 +1,891 @@ +/* + * Copyright © 2005, 2006 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id$ + */ + +#include <mozilla-config.h> +#include "config.h" + +#include <glib.h> +#include <glib-object.h> +#include <glib/gi18n.h> +#include <gtk/gtk.h> + +#include <nsStringAPI.h> + +#include <nsCOMPtr.h> +#include <nsIDOMWindow.h> +#include <nsServiceManagerUtils.h> + +#include "gecko-embed.h" +#include "gecko-embed-single.h" + +#include "AutoJSContextStack.h" +#include "AutoWindowModalState.h" +#include "GeckoUtils.h" + +#include "GeckoPromptService.h" + +#define TIMEOUT 1000 /* ms */ +#define TIMEOUT_DATA_KEY "timeout" + +#define MAX_MESSAGE_LENGTH 512 +#define MAX_TITLE_LENGTH 256 +#define MAX_BUTTON_TEXT_LENGTH 128 + +enum +{ + RESPONSE_ABORT_SCRIPT = 42 +}; + +class Prompter +{ +public: + Prompter (const char*, nsIDOMWindow*, const PRUnichar*, const PRUnichar*); + ~Prompter(); + + void AddStockButton (const char*, int); + void AddButtonWithFlags (PRInt32, PRUint32, const PRUnichar*, PRUint32); + void AddButtonsWithFlags (PRUint32, const PRUnichar*, const PRUnichar*, const PRUnichar*); + void AddCheckbox (const PRUnichar*, PRBool*); + void GetCheckboxState (PRBool *); + void AddEntry (const char *, const PRUnichar *, PRBool); + void GetText (PRUint32, PRUnichar **); + void AddSelect (PRUint32, const PRUnichar **, PRInt32); + void GetSelected (PRInt32*); + + PRInt32 Run (PRBool * = nsnull); + void Show (); + + PRBool IsCalledFromScript (); + void PerformScriptAbortion (); + + char *ConvertAndTruncateString (const PRUnichar *, PRInt32 = -1); + char* ConvertAndEscapeButtonText (const PRUnichar *, PRInt32 = -1); + +private: + nsCOMPtr<nsIDOMWindow> mWindow; + GtkDialog *mDialog; + GtkWidget *mVBox; + GtkWidget *mCheck; + GtkSizeGroup *mSizeGroup; + GtkWidget *mEntries[2]; + GtkWidget *mCombo; + PRInt32 mNumButtons; + PRInt32 mNumEntries; + PRInt32 mDefaultResponse; + PRInt32 mUnaffirmativeResponse; + PRInt32 mResponse; + PRBool mSuccess; + PRBool mDelay; +}; + +Prompter::Prompter (const char *aStock, + nsIDOMWindow *aParent, + const PRUnichar *aTitle, + const PRUnichar *aText) + : mWindow (aParent) + , mDialog(nsnull) + , mVBox(nsnull) + , mCheck(nsnull) + , mSizeGroup(nsnull) + , mCombo(nsnull) + , mNumButtons(0) + , mNumEntries(0) + , mDefaultResponse(GTK_RESPONSE_ACCEPT) + , mUnaffirmativeResponse(0) + , mResponse(GTK_RESPONSE_CANCEL) + , mSuccess(PR_FALSE) + , mDelay(PR_FALSE) +{ + GtkWidget *parent, *hbox, *label, *image; + + gecko_embed_single_push_startup (); + + mEntries[0] = mEntries[1] = nsnull; + + mDialog = GTK_DIALOG (gtk_dialog_new ()); + g_object_ref (mDialog); + gtk_object_sink (GTK_OBJECT (mDialog)); + + char *title = NULL; + if (aTitle) + { + title = ConvertAndTruncateString (aTitle, MAX_TITLE_LENGTH); + } + + gtk_window_set_title (GTK_WINDOW (mDialog), title ? title : ""); + g_free (title); + + gtk_window_set_modal (GTK_WINDOW (mDialog), TRUE); + + parent = GeckoUtils::GetGtkWindowForDOMWindow (aParent); + if (GTK_IS_WINDOW (parent)) + { + gtk_window_set_transient_for (GTK_WINDOW (mDialog), + GTK_WINDOW (parent)); + +#if !GTK_CHECK_VERSION (2,9,0) + if (GTK_WINDOW (parent)->group) + { + gtk_window_group_add_window (GTK_WINDOW (parent)->group, + GTK_WINDOW (mDialog)); + } +#endif + } + + gtk_dialog_set_has_separator (mDialog, FALSE); + gtk_window_set_resizable (GTK_WINDOW (mDialog), FALSE); + gtk_container_set_border_width (GTK_CONTAINER (mDialog), 5); + gtk_box_set_spacing (GTK_BOX (mDialog->vbox), 14); /* 2 * 5 + 14 = 24 */ + + hbox = gtk_hbox_new (FALSE, 12); + gtk_container_set_border_width (GTK_CONTAINER (hbox), 5); + gtk_container_add (GTK_CONTAINER (GTK_DIALOG (mDialog)->vbox), hbox); + + image = gtk_image_new_from_stock (aStock, GTK_ICON_SIZE_DIALOG); + gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0); + gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0); + + mVBox = gtk_vbox_new (FALSE, 12); + gtk_box_pack_start (GTK_BOX (hbox), mVBox, TRUE, TRUE, 0); + + char *text = NULL; + if (aText) + { + text = ConvertAndTruncateString (aText, MAX_MESSAGE_LENGTH); + } + + label = gtk_label_new (text); + g_free (text); + + gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); + /* Guard against overlong nonbreakable text (exploit) */ + gtk_label_set_line_wrap_mode (GTK_LABEL (label), PANGO_WRAP_WORD_CHAR); + gtk_label_set_selectable (GTK_LABEL (label), TRUE); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0); + + gtk_box_pack_start (GTK_BOX (mVBox), label, FALSE, FALSE, 0); + gtk_widget_show (label); + + if (IsCalledFromScript ()) + { + gtk_dialog_add_button (GTK_DIALOG (mDialog), + _("_Abort Script"), + RESPONSE_ABORT_SCRIPT); + } + + gtk_widget_show (image); + gtk_widget_show (mVBox); + gtk_widget_show (hbox); +} + +Prompter::~Prompter () +{ + if (mSizeGroup) + { + g_object_unref (mSizeGroup); + } + + gtk_widget_destroy (GTK_WIDGET (mDialog)); + g_object_unref (mDialog); + + gecko_embed_single_pop_startup (); +} + +void +Prompter::AddStockButton (const char *aStock, + int aResponse) +{ + gtk_dialog_add_button (GTK_DIALOG (mDialog), + aStock, aResponse); + ++mNumButtons; +} + +void +Prompter::AddButtonWithFlags (PRInt32 aNum, + PRUint32 aFlags, + const PRUnichar *aText, + PRUint32 aDefault) +{ + if (aFlags == 0) return; + + const char *label = NULL; + char *freeme = NULL; + gboolean isAffirmative = FALSE; + switch (aFlags) + { + case nsIPromptService::BUTTON_TITLE_OK: + label = GTK_STOCK_OK; + isAffirmative = TRUE; + break; + + case nsIPromptService::BUTTON_TITLE_CANCEL: + label = GTK_STOCK_CANCEL; + break; + + case nsIPromptService::BUTTON_TITLE_YES: + label = GTK_STOCK_YES; + isAffirmative = TRUE; + break; + + case nsIPromptService::BUTTON_TITLE_NO: + label = GTK_STOCK_NO; + break; + + case nsIPromptService::BUTTON_TITLE_SAVE: + label = GTK_STOCK_SAVE; + isAffirmative = TRUE; + break; + + case nsIPromptService::BUTTON_TITLE_DONT_SAVE: + label = _("Don't Save"); + break; + + case nsIPromptService::BUTTON_TITLE_REVERT: + label = GTK_STOCK_REVERT_TO_SAVED; + break; + + case nsIPromptService::BUTTON_TITLE_IS_STRING: + default: + label = freeme = ConvertAndEscapeButtonText (aText, MAX_BUTTON_TEXT_LENGTH); + /* We can't tell, so assume it's affirmative */ + isAffirmative = TRUE; + break; + } + + if (label == NULL) return; + + gtk_dialog_add_button (mDialog, label, aNum); + ++mNumButtons; + + if (isAffirmative && mDelay) + { + gtk_dialog_set_response_sensitive (mDialog, aNum, FALSE); + } + + if (!isAffirmative) + { + mUnaffirmativeResponse = aNum; + } + + if (aDefault) + { + mDefaultResponse = aNum; + } + + g_free (freeme); +} + +void +Prompter::AddButtonsWithFlags (PRUint32 aFlags, + const PRUnichar *aText0, + const PRUnichar *aText1, + const PRUnichar *aText2) +{ + mDelay = (aFlags & nsIPromptService::BUTTON_DELAY_ENABLE) != 0; + mDefaultResponse = -1; + + /* Reverse the order, on the assumption that what we passed is the + * 'windows' button order, and we want HIG order. + */ + AddButtonWithFlags (2, ((aFlags / nsIPromptService::BUTTON_POS_2) & 0xff), aText2, + aFlags & nsIPromptService::BUTTON_POS_2_DEFAULT); + AddButtonWithFlags (1, ((aFlags / nsIPromptService::BUTTON_POS_1) & 0xff), aText1, + aFlags & nsIPromptService::BUTTON_POS_1_DEFAULT); + AddButtonWithFlags (0, ((aFlags / nsIPromptService::BUTTON_POS_0) & 0xff), aText0, + aFlags & nsIPromptService::BUTTON_POS_0_DEFAULT); + + /* If no default was set, use the 'rightmost' unaffirmative response. + * This happens with the suite's password manager prompt. + */ + if (mDefaultResponse == -1) + { + mDefaultResponse = mUnaffirmativeResponse; + } +} + +void +Prompter::AddCheckbox (const PRUnichar *aText, + PRBool *aState) +{ + if (!aState || !aText) return; + + char *label = ConvertAndEscapeButtonText (aText, 2 * MAX_BUTTON_TEXT_LENGTH); + mCheck = gtk_check_button_new_with_mnemonic (label); + g_free (label); + + gtk_label_set_line_wrap (GTK_LABEL (GTK_BIN (mCheck)->child), TRUE); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mCheck), *aState); + gtk_box_pack_start (GTK_BOX (mVBox), mCheck, FALSE, FALSE, 0); + gtk_widget_show (mCheck); +} + +void +Prompter::GetCheckboxState (PRBool *aState) +{ + if (!aState || !mCheck) return; + + *aState = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (mCheck)); +} + +void +Prompter::AddEntry (const char *aLabel, + const PRUnichar *aValue, + PRBool aIsPassword) +{ + if (!mSizeGroup) + { + mSizeGroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + } + + GtkWidget *hbox = gtk_hbox_new (FALSE, 12); + gtk_box_pack_start (GTK_BOX (mVBox), hbox, FALSE, FALSE, 0); + + GtkWidget *label = nsnull; + if (aLabel) + { + label = gtk_label_new_with_mnemonic (aLabel); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); + gtk_size_group_add_widget (mSizeGroup, label); + } + + GtkWidget *entry = mEntries[mNumEntries++] = gtk_entry_new (); + gtk_entry_set_visibility (GTK_ENTRY (entry), !aIsPassword); + gtk_entry_set_activates_default(GTK_ENTRY (entry), TRUE); + + if (aValue) + { + nsCString cValue; + NS_UTF16ToCString (nsDependentString(aValue), + NS_CSTRING_ENCODING_UTF8, cValue); + + gtk_entry_set_text (GTK_ENTRY (entry), cValue.get()); + } + + if (label) + { + gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry); + } + + gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0); + gtk_widget_show_all (hbox); +} + +void +Prompter::GetText (PRUint32 aNum, + PRUnichar **aValue) +{ + if (!aValue || !mEntries[aNum]) return; + + const char *text = gtk_entry_get_text (GTK_ENTRY (mEntries[aNum])); + if (!text) return; + + nsString value; + NS_CStringToUTF16 (nsDependentCString (text), + NS_CSTRING_ENCODING_UTF8, value); + + *aValue = NS_StringCloneData (value); +} + +void +Prompter::AddSelect (PRUint32 aCount, + const PRUnichar **aList, + PRInt32 aDefault) +{ + mCombo = gtk_combo_box_new_text (); + + for (PRUint32 i = 0; i < aCount; i++) + { + /* FIXME: use "" instead in this case? */ + if (!aList[i] || !aList[i][0]) continue; + + nsCString cData; + NS_UTF16ToCString (nsDependentString(aList[i]), NS_CSTRING_ENCODING_UTF8, cData); + + gtk_combo_box_append_text (GTK_COMBO_BOX (mCombo), cData.get()); + } + + gtk_combo_box_set_active (GTK_COMBO_BOX (mCombo), aDefault); + + gtk_box_pack_start (GTK_BOX (mVBox), mCombo, FALSE, FALSE, 0); + gtk_widget_show (mCombo); +} + +void +Prompter::GetSelected (PRInt32 *aSelected) +{ + if (!aSelected || !mCombo) return; + + *aSelected = gtk_combo_box_get_active (GTK_COMBO_BOX (mCombo)); +} + +static gboolean +EnableResponse (GtkDialog *aDialog) +{ + g_object_steal_data (G_OBJECT (aDialog), TIMEOUT_DATA_KEY); + + gtk_dialog_set_response_sensitive (aDialog, 0, TRUE); + gtk_dialog_set_response_sensitive (aDialog, 1, TRUE); + gtk_dialog_set_response_sensitive (aDialog, 2, TRUE); + + return FALSE; +} + +static void +RemoveTimeout (gpointer idptr) +{ + guint timeout = GPOINTER_TO_UINT (idptr); + + g_return_if_fail (timeout != 0); + + g_source_remove (timeout); +} + +PRInt32 +Prompter::Run (PRBool *aSuccess) +{ +#if 0 + AutoEventQueue queue; + if (NS_FAILED (queue.Init())) + { + if (aSuccess) + { + *aSuccess = PR_FALSE; + } + mSuccess = PR_FALSE; + + return GTK_RESPONSE_CANCEL; + } +#endif + + nsresult rv; + AutoJSContextStack stack; + rv = stack.Init (); + if (NS_FAILED (rv)) return rv; + + AutoWindowModalState modalState (mWindow); + + if (mDelay) + { + guint timeout = g_timeout_add (TIMEOUT, + (GSourceFunc) EnableResponse, + mDialog); + g_object_set_data_full (G_OBJECT (mDialog), TIMEOUT_DATA_KEY, + GUINT_TO_POINTER (timeout), + (GDestroyNotify) RemoveTimeout); + } + + gtk_dialog_set_default_response (GTK_DIALOG (mDialog), mDefaultResponse); + + GtkWidget *widget = GTK_WIDGET (mDialog); + gtk_widget_show (widget); + mResponse = gtk_dialog_run (mDialog); + gtk_widget_hide (widget); + + g_object_set_data (G_OBJECT (mDialog), TIMEOUT_DATA_KEY, NULL); + + mSuccess = (GTK_RESPONSE_ACCEPT == mResponse); + if (aSuccess) + { + *aSuccess = mSuccess; + } + + if (mResponse == RESPONSE_ABORT_SCRIPT) + { + PerformScriptAbortion (); + } + + return mResponse; +} + +static void +DeletePrompter (gpointer aPromptPtr, + GObject *aZombie) +{ + Prompter *prompt = static_cast<Prompter*>(aPromptPtr); + + delete prompt; +} + +void +Prompter::Show () +{ + /* We don't need it anymore */ + mWindow = nsnull; + + gtk_window_set_modal (GTK_WINDOW (mDialog), FALSE); + + g_signal_connect (mDialog, "response", + G_CALLBACK (gtk_widget_destroy), NULL); + g_object_weak_ref (G_OBJECT (mDialog), + (GWeakNotify) DeletePrompter, + static_cast<gpointer>(this)); + + gtk_widget_show (GTK_WIDGET (mDialog)); +} + +PRBool +Prompter::IsCalledFromScript() +{ +#if 0 + nsCOMPtr<nsIXPConnect> xpconnect (do_GetService (nsIXPConnect::GetCID())); + NS_ENSURE_TRUE (xpconnect, PR_FALSE); + + nsresult rv; + nsCOMPtr<nsIXPCNativeCallContext> ncc; + rv = xpconnect->GetCurrentNativeCallContext (getter_AddRefs (ncc)); + NS_ENSURE_SUCCESS (rv, PR_FALSE); + + if (!ncc) return PR_FALSE; + + JSContext *cx = nsnull; + rv = ncc->GetJSContext (&cx); + g_print ("GetJSContext rv=%x, cx=%p\n", rv, cx); + + NS_ENSURE_SUCCESS (rv, PR_FALSE); + + return cx != nsnull; +#endif + return PR_FALSE; +} + +void +Prompter::PerformScriptAbortion() +{ +#if 0 + /* FIXME: can we only stop the calling script, not all scripts in the context? */ + + nsCOMPtr<nsIXPConnect> xpconnect (do_GetService (nsIXPConnect::GetCID())); + NS_ENSURE_TRUE (xpconnect, ); + + nsresult rv; + nsCOMPtr<nsIXPCNativeCallContext> ncc; + rv = xpconnect->GetCurrentNativeCallContext (getter_AddRefs (ncc)); + NS_ENSURE_SUCCESS (rv, ); + NS_ENSURE_TRUE (ncc, ); + + JSContext *cx = nsnull; + rv = ncc->GetJSContext (&cx); + g_print ("GetJSContext rv=%x, cx=%p\n", rv, cx); + NS_ENSURE_SUCCESS (rv, ); + NS_ENSURE_TRUE (cx, ); + + g_print ("Would now disable scripts\n"); +// MozillaPrivate::SetScriptsEnabled (cx, PR_FALSE, PR_FALSE); +#endif +} + +char * +Prompter::ConvertAndTruncateString (const PRUnichar *aText, + PRInt32 aMaxLength) +{ + if (aText == nsnull) return NULL; + + /* This depends on the assumption that + * typeof(PRUnichar) == typeof (gunichar2) == uint16, + * which should be pretty safe. + */ + glong n_read = 0, n_written = 0; + char *converted = g_utf16_to_utf8 ((gunichar2*) aText, aMaxLength, + &n_read, &n_written, NULL); + /* FIXME loop from the end while !g_unichar_isspace (char)? */ + + return converted; +} + +char * +Prompter::ConvertAndEscapeButtonText(const PRUnichar *aText, + PRInt32 aMaxLength) +{ + char *converted = ConvertAndTruncateString (aText, aMaxLength); + if (converted == NULL) return NULL; + + char *escaped = (char*) g_malloc (strlen (converted) + 1); + char *q = escaped; + for (const char *p = converted; *p; ++p, ++q) + { + if (*p == '&') + { + if (*(p+1) == '&') + { + *q = '&'; + ++p; + } + else + { + *q = '_'; + } + } + else + { + *q = *p; + } + } + + /* Null termination */ + *q = '\0'; + + g_free (converted); + + return escaped; +} + +/* FIXME: needs THREADSAFE? */ +#if HAVE_NSINONBLOCKINGALERTSERVICE_H +NS_IMPL_ISUPPORTS2 (GeckoPromptService, + nsIPromptService, + nsINonBlockingAlertService) +#else +NS_IMPL_ISUPPORTS1 (GeckoPromptService, + nsIPromptService) +#endif + +GeckoPromptService::GeckoPromptService() +{ +} + +GeckoPromptService::~GeckoPromptService() +{ +} + +/* nsIPromptService implementation */ + +/* void alert (in nsIDOMWindow aParent, in wstring aDialogTitle, in wstring aText); */ +NS_IMETHODIMP +GeckoPromptService::Alert (nsIDOMWindow *aParent, + const PRUnichar *aDialogTitle, + const PRUnichar *aText) +{ + Prompter prompt (GTK_STOCK_DIALOG_INFO, aParent, aDialogTitle, aText); + prompt.AddStockButton (GTK_STOCK_OK, GTK_RESPONSE_ACCEPT); + prompt.Run (); + + return NS_OK; +} + +/* void alertCheck (in nsIDOMWindow aParent, in wstring aDialogTitle, in wstring aText, in wstring aCheckMsg, inout boolean aCheckState); */ +NS_IMETHODIMP +GeckoPromptService::AlertCheck (nsIDOMWindow *aParent, + const PRUnichar *aDialogTitle, + const PRUnichar *aText, + const PRUnichar *aCheckMsg, + PRBool *aCheckState) +{ + Prompter prompt (GTK_STOCK_DIALOG_INFO, aParent, aDialogTitle, aText); + prompt.AddStockButton (GTK_STOCK_OK, GTK_RESPONSE_ACCEPT); + prompt.AddCheckbox (aCheckMsg, aCheckState); + + prompt.Run (); + prompt.GetCheckboxState (aCheckState); + + return NS_OK; +} + +/* boolean confirm (in nsIDOMWindow aParent, in wstring aDialogTitle, in wstring aText); */ +NS_IMETHODIMP +GeckoPromptService::Confirm (nsIDOMWindow *aParent, + const PRUnichar *aDialogTitle, + const PRUnichar *aText, + PRBool *_retval) +{ + NS_ENSURE_ARG_POINTER (_retval); + + Prompter prompt (GTK_STOCK_DIALOG_QUESTION, aParent, aDialogTitle, aText); + prompt.AddStockButton (GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); + prompt.AddStockButton (GTK_STOCK_OK, GTK_RESPONSE_ACCEPT); + prompt.Run (_retval); + + return NS_OK; +} + +/* boolean confirmCheck (in nsIDOMWindow aParent, in wstring aDialogTitle, in wstring aText, in wstring aCheckMsg, inout boolean aCheckState); */ +NS_IMETHODIMP +GeckoPromptService::ConfirmCheck (nsIDOMWindow *aParent, + const PRUnichar *aDialogTitle, + const PRUnichar *aText, + const PRUnichar *aCheckMsg, + PRBool *aCheckState, + PRBool *_retval) +{ + NS_ENSURE_ARG_POINTER (_retval); + + Prompter prompt (GTK_STOCK_DIALOG_QUESTION, aParent, aDialogTitle, aText); + prompt.AddStockButton (GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); + prompt.AddStockButton (GTK_STOCK_OK, GTK_RESPONSE_ACCEPT); + prompt.AddCheckbox (aCheckMsg, aCheckState); + + prompt.Run (_retval); + prompt.GetCheckboxState (aCheckState); + + return NS_OK; +} + +/* PRInt32 confirmEx (in nsIDOMWindow aParent, in wstring aDialogTitle, in wstring aText, in unsigned long aButtonFlags, in wstring aButton0Title, in wstring aButton1Title, in wstring aButton2Title, in wstring aCheckMsg, inout boolean aCheckState); */ +NS_IMETHODIMP +GeckoPromptService::ConfirmEx (nsIDOMWindow *aParent, + const PRUnichar *aDialogTitle, + const PRUnichar *aText, + PRUint32 aButtonFlags, + const PRUnichar *aButton0Title, + const PRUnichar *aButton1Title, + const PRUnichar *aButton2Title, + const PRUnichar *aCheckMsg, + PRBool *aCheckState, + PRInt32 *_retval) +{ + NS_ENSURE_ARG_POINTER (_retval); + + Prompter prompt (GTK_STOCK_DIALOG_QUESTION, aParent, aDialogTitle, aText); + prompt.AddButtonsWithFlags (aButtonFlags, aButton0Title, + aButton1Title, aButton2Title); + prompt.AddCheckbox (aCheckMsg, aCheckState); + + *_retval = prompt.Run (nsnull); + prompt.GetCheckboxState (aCheckState); + + return NS_OK; +} + +/* boolean prompt (in nsIDOMWindow aParent, in wstring aDialogTitle, in wstring aText, inout wstring aValue, in wstring aCheckMsg, inout boolean aCheckState); */ +NS_IMETHODIMP +GeckoPromptService::Prompt (nsIDOMWindow *aParent, + const PRUnichar *aDialogTitle, + const PRUnichar *aText, + PRUnichar **aValue, + const PRUnichar *aCheckMsg, + PRBool *aCheckState, + PRBool *_retval) +{ + NS_ENSURE_ARG_POINTER (_retval); + NS_ENSURE_ARG_POINTER (aValue); + + Prompter prompt (GTK_STOCK_DIALOG_QUESTION, aParent, aDialogTitle, aText); + prompt.AddStockButton (GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); + prompt.AddStockButton (GTK_STOCK_OK, GTK_RESPONSE_ACCEPT); + prompt.AddEntry (nsnull, *aValue, PR_FALSE); + prompt.AddCheckbox (aCheckMsg, aCheckState); + + prompt.Run (_retval); + prompt.GetText (0, aValue); + prompt.GetCheckboxState (aCheckState); + + return NS_OK; +} + +/* boolean promptUsernameAndPassword (in nsIDOMWindow aParent, in wstring aDialogTitle, in wstring aText, inout wstring aUsername, inout wstring aPassword, in wstring aCheckMsg, inout boolean aCheckState); */ +NS_IMETHODIMP +GeckoPromptService::PromptUsernameAndPassword (nsIDOMWindow *aParent, + const PRUnichar *aDialogTitle, + const PRUnichar *aText, + PRUnichar **aUsername, + PRUnichar **aPassword, + const PRUnichar *aCheckMsg, + PRBool *aCheckState, + PRBool *_retval) +{ + NS_ENSURE_ARG_POINTER (_retval); + NS_ENSURE_ARG_POINTER (aUsername); + NS_ENSURE_ARG_POINTER (aPassword); + + Prompter prompt (GTK_STOCK_DIALOG_AUTHENTICATION, aParent, aDialogTitle, aText); + prompt.AddStockButton (GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); + prompt.AddStockButton (GTK_STOCK_OK, GTK_RESPONSE_ACCEPT); + prompt.AddEntry (_("_Username:"), *aUsername, PR_FALSE); + prompt.AddEntry (_("_Password:"), *aPassword, PR_TRUE); + prompt.AddCheckbox (aCheckMsg, aCheckState); + + prompt.Run (_retval); + prompt.GetText (0, aUsername); + prompt.GetText (1, aPassword); + prompt.GetCheckboxState (aCheckState); + + return NS_OK; +} + +/* boolean promptPassword (in nsIDOMWindow aParent, in wstring aDialogTitle, in wstring aText, inout wstring aPassword, in wstring aCheckMsg, inout boolean aCheckState); */ +NS_IMETHODIMP +GeckoPromptService::PromptPassword (nsIDOMWindow *aParent, + const PRUnichar *aDialogTitle, + const PRUnichar *aText, + PRUnichar **aPassword, + const PRUnichar *aCheckMsg, + PRBool *aCheckState, + PRBool *_retval) +{ + NS_ENSURE_ARG_POINTER (_retval); + NS_ENSURE_ARG_POINTER (aPassword); + + Prompter prompt (GTK_STOCK_DIALOG_AUTHENTICATION, aParent, aDialogTitle, aText); + prompt.AddStockButton (GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); + prompt.AddStockButton (GTK_STOCK_OK, GTK_RESPONSE_ACCEPT); + prompt.AddEntry (_("_Password:"), *aPassword, PR_TRUE); + prompt.AddCheckbox (aCheckMsg, aCheckState); + + // FIXME: Add a CAPSLOCK indicator? + + prompt.Run (_retval); + prompt.GetText (0, aPassword); + prompt.GetCheckboxState (aCheckState); + + return NS_OK; +} + +/* boolean select (in nsIDOMWindow aParent, in wstring aDialogTitle, in wstring aText, in PRUint32 aCount, [array, size_is (aCount)] in wstring aSelectList, out long aOutSelection); */ +NS_IMETHODIMP +GeckoPromptService::Select (nsIDOMWindow *aParent, + const PRUnichar *aDialogTitle, + const PRUnichar *aText, + PRUint32 aCount, + const PRUnichar **aSelectList, + PRInt32 *aOutSelection, + PRBool *_retval) +{ + NS_ENSURE_ARG_POINTER (_retval); + NS_ENSURE_ARG_POINTER (aOutSelection); + + Prompter prompt (GTK_STOCK_DIALOG_QUESTION, aParent, aDialogTitle, aText); + prompt.AddStockButton (GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); + prompt.AddStockButton (GTK_STOCK_OK, GTK_RESPONSE_ACCEPT); + prompt.AddSelect (aCount, aSelectList, *aOutSelection); + + prompt.Run (_retval); + prompt.GetSelected (aOutSelection); + + return NS_OK; +} + +#if HAVE_NSINONBLOCKINGALERTSERVICE_H + +/* showNonBlockingAlert (in nsIDOMWindow aParent, in wstring aDialogTitle, in wstring aText); */ +NS_IMETHODIMP +GeckoPromptService::ShowNonBlockingAlert (nsIDOMWindow *aParent, + const PRUnichar *aDialogTitle, + const PRUnichar *aText) +{ + Prompter *prompt = new Prompter (GTK_STOCK_DIALOG_INFO, aParent, aDialogTitle, aText); + if (!prompt) return NS_ERROR_OUT_OF_MEMORY; + + prompt->AddStockButton (GTK_STOCK_OK, GTK_RESPONSE_ACCEPT); + prompt->Show (); + + return NS_OK; +} + +#endif /* HAVE_NSINONBLOCKINGALERTSERVICE_H */ diff --git a/embed/xulrunner/src/GeckoPromptService.h b/embed/xulrunner/src/GeckoPromptService.h new file mode 100644 index 000000000..b2ef610b8 --- /dev/null +++ b/embed/xulrunner/src/GeckoPromptService.h @@ -0,0 +1,53 @@ +/* + * Copyright © 2005, 2006 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id$ + */ + +#ifndef GECKO_PROMPT_SERVICE_H +#define GECKO_PROMPT_SERVICE_H + +#include <nsIPromptService.h> + +#if HAVE_NSINONBLOCKINGALERTSERVICE_H +#include <nsINonBlockingAlertService.h> +#endif + +#define GECKO_PROMPT_SERVICE_CID \ +{ /* cadc6035-7c53-4039-823b-004a289d5eb2 */ \ + 0xcadc6035, 0x7c53, 0x4039, \ + { 0x82, 0x3b, 0x00, 0x4a, 0x28, 0x9d, 0x5e, 0xb2 } } + +#define GECKO_PROMPT_SERVICE_CLASSNAME "Gecko Prompt Service" + +class GeckoPromptService : public nsIPromptService +#if HAVE_NSINONBLOCKINGALERTSERVICE_H + , public nsINonBlockingAlertService +#endif +{ + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIPROMPTSERVICE +#if HAVE_NSINONBLOCKINGALERTSERVICE_H + NS_DECL_NSINONBLOCKINGALERTSERVICE +#endif + + GeckoPromptService(); + virtual ~GeckoPromptService(); +}; + +#endif /* GECKO_PROMPT_SERVICE_H */ diff --git a/embed/xulrunner/src/GeckoSingle.cpp b/embed/xulrunner/src/GeckoSingle.cpp new file mode 100644 index 000000000..4b5d8e467 --- /dev/null +++ b/embed/xulrunner/src/GeckoSingle.cpp @@ -0,0 +1,122 @@ +/* + * Copyright © Christopher Blizzard + * Copyright © 2006 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * --------------------------------------------------------------------------- + * Derived from Mozilla.org code, which had the following attributions: + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright © Christopher Blizzard. All Rights Reserved. + * Portions created by the Initial Developer are Copyright © 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Christopher Blizzard <blizzard@mozilla.org> + * --------------------------------------------------------------------------- + * + * $Id$ + */ + +#include <mozilla-config.h> +#include <config.h> + +#include <stdlib.h> +#include "nsIDocShell.h" +#include "nsIWebProgress.h" +#include "nsIWebBrowserStream.h" +#include "nsIWidget.h" + +// all of our local includes +#include "GeckoSingle.h" +#include "EmbedWindow.h" +#include "gecko-init.h" +#include "gecko-init-private.h" + +GSList *GeckoSingle::sWindowList = nsnull; +PRUint32 GeckoSingle::sWidgetCount = 0; + +GeckoSingle::GeckoSingle() +{ +} + +GeckoSingle::~GeckoSingle() +{ +} + +/* static */ +GeckoBrowser * +GeckoSingle::FindPrivateForBrowser(nsIWebBrowserChrome *aBrowser) +{ + // This function doesn't get called very often at all ( only when + // creating a new window ) so it's OK to walk the list of open + // windows. + for (GSList *l = sWindowList; l != NULL; l = l->next) { + GeckoBrowser *tmpPrivate = static_cast<GeckoBrowser *>(l->data); + // get the browser object for that window + nsIWebBrowserChrome *chrome = static_cast<nsIWebBrowserChrome *> + (tmpPrivate->mWindow); + if (chrome == aBrowser) + return tmpPrivate; + } + + return nsnull; +} + +/* static */ +void +GeckoSingle::ReparentToOffscreen (GtkWidget* aWidget) +{ + gecko_reparent_to_offscreen (aWidget); +} + +/* static */ +void +GeckoSingle::AddBrowser(GeckoBrowser *aBrowser) +{ + PushStartup(); + sWindowList = g_slist_prepend (sWindowList, aBrowser); +} + +/* static */ +void +GeckoSingle::RemoveBrowser(GeckoBrowser *aBrowser) +{ + sWindowList = g_slist_remove (sWindowList, aBrowser); + PopStartup(); +} + +/* static */ +void +GeckoSingle::PushStartup() +{ + GeckoSingle::sWidgetCount++; +} + +/* static */ +void +GeckoSingle::PopStartup() +{ + GeckoSingle::sWidgetCount--; + if (GeckoSingle::sWidgetCount == 0) { + gecko_shutdown(); +#ifdef XPCOM_GLUE + XPCOMGlueShutdown(); +#endif + } +} diff --git a/embed/xulrunner/src/GeckoSingle.h b/embed/xulrunner/src/GeckoSingle.h new file mode 100644 index 000000000..7654d9a9d --- /dev/null +++ b/embed/xulrunner/src/GeckoSingle.h @@ -0,0 +1,97 @@ +/* + * Copyright © Christopher Blizzard + * Copyright © 2006 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * --------------------------------------------------------------------------- + * Derived from Mozilla.org code, which had the following attributions: + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright © Christopher Blizzard. All Rights Reserved. + * Portions created by the Initial Developer are Copyright © 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Christopher Blizzard <blizzard@mozilla.org> + * --------------------------------------------------------------------------- + * + * $Id$ + */ + +#ifndef __GeckoSingle_h +#define __GeckoSingle_h + +#include <nsCOMPtr.h> +#include <nsEmbedString.h> +#include <nsIWebNavigation.h> +#include <nsISHistory.h> +// for our one function that gets the GeckoSingle via the chrome +// object. +#include <nsIWebBrowserChrome.h> +#include <nsIAppShell.h> +// app component registration +#include <nsIGenericFactory.h> +#include <nsIComponentRegistrar.h> + +#include "gecko-embed-single.h" +#include "gecko-embed.h" + +#include "GeckoBrowser.h" + +class EmbedProfile; +class EmbedProgress; +class EmbedWindow; +class EmbedContentListener; +class EmbedEventListener; + +class nsPIDOMWindow; +class nsIDirectoryServiceProvider; +class nsProfileDirServiceProvider; + +class GeckoSingle +{ + friend class GeckoBrowser; + + public: + + GeckoSingle(); + ~GeckoSingle(); + + static void PushStartup (); + static void PopStartup (); + + // static GeckoSingle* GetInstance(); + + // This function will find the specific GeckoBrowser object for a + // given nsIWebBrowserChrome. + static GeckoBrowser *FindPrivateForBrowser(nsIWebBrowserChrome *aBrowser); + + // the number of widgets that have been created + static PRUint32 sWidgetCount; + // the list of application-specific components to register + static const nsModuleComponentInfo *sAppComps; + static int sNumAppComps; + // the list of all open windows + static GSList *sWindowList; + + static void ReparentToOffscreen (GtkWidget *aWidget); + static void AddBrowser (GeckoBrowser *aBrowser); + static void RemoveBrowser (GeckoBrowser *aBrowser); +}; + +#endif /* __GeckoSingle_h */ diff --git a/embed/xulrunner/src/GeckoUtils.cpp b/embed/xulrunner/src/GeckoUtils.cpp new file mode 100644 index 000000000..b9d6e3f53 --- /dev/null +++ b/embed/xulrunner/src/GeckoUtils.cpp @@ -0,0 +1,87 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright © 2003 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Brian Ryner <bryner@brianryner.com> + * + * $Id$ + */ + +#include <mozilla-config.h> +#include "config.h" + +#include "GeckoUtils.h" + +#include "gecko-embed.h" + +#include <nsCOMPtr.h> +#include <nsIDOMWindow.h> +#include <nsIWindowWatcher.h> +#include <nsIWebBrowserChrome.h> +#include <nsIEmbeddingSiteWindow.h> +#include <nsIServiceManager.h> +#include <nsServiceManagerUtils.h> + +GtkWidget * +GeckoUtils::GetGeckoEmbedForDOMWindow (nsIDOMWindow * aDOMWindow) +{ + if (!aDOMWindow) + return NULL; + + /* Get the toplevel DOM window, in case this window is a frame */ + nsCOMPtr<nsIDOMWindow> domWin; + aDOMWindow->GetTop (getter_AddRefs (domWin)); + if (!domWin) + return NULL; + + nsCOMPtr< nsIWindowWatcher> wwatch + (do_GetService ("@mozilla.org/embedcomp/window-watcher;1")); + NS_ENSURE_TRUE (wwatch, NULL); + + nsCOMPtr<nsIWebBrowserChrome> chrome; + wwatch->GetChromeForWindow (domWin, getter_AddRefs (chrome)); + + nsCOMPtr <nsIEmbeddingSiteWindow> siteWindow (do_QueryInterface (chrome)); + if (!siteWindow) + return NULL; + + GtkWidget *widget; + siteWindow->GetSiteWindow ((void **) &widget); + if (!widget || !GECKO_IS_EMBED (widget)) + return NULL; + + return widget; +} + +GtkWidget * +GeckoUtils::GetGtkWindowForDOMWindow (nsIDOMWindow * aDOMWindow) +{ + GtkWidget *embed = GeckoUtils::GetGeckoEmbedForDOMWindow (aDOMWindow); + if (!embed) + return NULL; + + GtkWidget *gtkWin = gtk_widget_get_toplevel (embed); + if (!GTK_WIDGET_TOPLEVEL (gtkWin)) + return NULL; + + return gtkWin; +} diff --git a/embed/xulrunner/src/GeckoUtils.h b/embed/xulrunner/src/GeckoUtils.h new file mode 100644 index 000000000..05012e6b2 --- /dev/null +++ b/embed/xulrunner/src/GeckoUtils.h @@ -0,0 +1,34 @@ +/* + * Copyright © 2006 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id$ + */ + +#ifndef GECKO_UTILS_H +#define GECKO_UTILS_H + +#include <gtk/gtkwidget.h> + +class nsIDOMWindow; + +namespace GeckoUtils +{ + GtkWidget* GetGeckoEmbedForDOMWindow (nsIDOMWindow*); + GtkWidget* GetGtkWindowForDOMWindow (nsIDOMWindow*); +} + +#endif diff --git a/embed/xulrunner/src/Makefile.am b/embed/xulrunner/src/Makefile.am new file mode 100644 index 000000000..a3afed257 --- /dev/null +++ b/embed/xulrunner/src/Makefile.am @@ -0,0 +1,167 @@ +NULL = + +required = \ + . \ + accessibility \ + content \ + embedcomponents \ + docshell \ + dom \ + embed_base \ + gfx \ + intl \ + js \ + layout \ + necko \ + profdirserviceprovider \ + shistory \ + string \ + uriloader \ + webbrwsr \ + webshell \ + widget \ + windowwatcher \ + xpcom \ + xpconnect \ + xulapp \ + $(NULL) + +MARSHALERS = gecko-embed-marshal.h gecko-embed-marshal.cpp +TYPES_SOURCES = gecko-embed-type-builtins.h gecko-embed-type-builtins.cpp + +BUILT_SOURCES= $(MARSHALERS) $(TYPES_SOURCES) + +gecko-embed-marshal.cpp: gecko-embed-marshal.list + $(GLIB_GENMARSHAL) --prefix=gecko_embed_marshal $< --header --body > $@ + +gecko-embed-marshal.h: gecko-embed-marshal.list + $(GLIB_GENMARSHAL) --prefix=gecko_embed_marshal $< --header > $@ + +TYPES_H_FILES = \ + gecko-embed-types.h \ + $(NULL) + +stamp_files = \ + stamp-gecko-embed-type-builtins.cpp \ + stamp-gecko-embed-type-builtins.h \ + $(NULL) + +gecko-embed-type-builtins.cpp: stamp-gecko-embed-type-builtins.cpp Makefile + @true +stamp-gecko-embed-type-builtins.cpp: Makefile $(TYPES_H_FILES) + $(GLIB_MKENUMS) \ + --fhead "#include \"gecko-embed-type-builtins.h\"\n\n" \ + --fprod "\n/* enumerations from \"@filename@\" */" \ + --fprod "\n#include \"@filename@\"" \ + --vhead "GType\n@enum_name@_get_type (void)\n{\n" \ + --vhead " static GType type = 0;\n\n" \ + --vhead " if (G_UNLIKELY (type == 0))\n {\n" \ + --vhead " static const G@Type@Value _@enum_name@_values[] = {" \ + --vprod " { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \ + --vtail " { 0, NULL, NULL }\n };\n\n" \ + --vtail " type = g_@type@_register_static (\"@EnumName@\", _@enum_name@_values);\n }\n\n" \ + --vtail " return type;\n}\n\n" \ + $(filter-out $<,$^) > xgen-$(@F) \ + && ( cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%) ) \ + && rm -f xgen-$(@F) \ + && echo timestamp > $(@F) + +gecko-embed-type-builtins.h: stamp-gecko-embed-type-builtins.h Makefile + @true +stamp-gecko-embed-type-builtins.h: Makefile $(TYPES_H_FILES) + $(GLIB_MKENUMS) \ + --fhead "#ifndef GECKO_TYPE_BUILTINS_H\n" \ + --fhead "#define GECKO_TYPE_BUILTINS_H 1\n\n" \ + --fhead "#include <glib-object.h>\n\n" \ + --fhead "G_BEGIN_DECLS\n\n" \ + --ftail "G_END_DECLS\n\n" \ + --ftail "#endif /* GECKO_TYPE_BUILTINS_H */\n" \ + --fprod "\n/* --- @filename@ --- */" \ + --eprod "#define GECKO_TYPE_@ENUMSHORT@ @enum_name@_get_type()\n" \ + --eprod "GType @enum_name@_get_type (void);\n" \ + $(filter-out $<,$^) > xgen-$(@F) \ + && ( cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%) ) \ + && rm -f xgen-$(@F) \ + && echo timestamp > $(@F) + +lib_LTLIBRARIES = libgnomegeckoembed-0.0.la + +libgnomegeckoembed_0_0_la_SOURCES = \ + $(MARSHALERS) \ + $(TYPES_SOURCES) \ + gecko-dom-event.cpp \ + gecko-dom-event.h \ + gecko-dom-event-internal.h \ + gecko-dom-event-private.h \ + gecko-embed.cpp \ + gecko-embed.h \ + gecko-embed-private.h \ + gecko-embed-signals.h \ + gecko-embed-single.cpp \ + gecko-embed-single.h \ + gecko-embed-single-private.h \ + gecko-embed-types.h \ + gecko-init.cpp \ + gecko-init.h \ + gecko-init-internal.h \ + gecko-init-private.h \ + AutoJSContextStack.cpp \ + AutoJSContextStack.h \ + AutoWindowModalState.cpp \ + AutoWindowModalState.h \ + EmbedContentListener.cpp \ + EmbedContentListener.h \ + EmbedEventListener.cpp \ + EmbedEventListener.h \ + EmbedProgress.cpp \ + EmbedProgress.h \ + EmbedWindow.cpp \ + EmbedWindowCreator.cpp \ + EmbedWindowCreator.h \ + EmbedWindow.h \ + GeckoBrowser.cpp \ + GeckoBrowser.h \ + GeckoPromptService.cpp \ + GeckoPromptService.h \ + GeckoSingle.cpp \ + GeckoSingle.h \ + GeckoUtils.cpp \ + GeckoUtils.h \ + $(NULL) + +libgnomegeckoembed_0_0_la_CPPFLAGS = \ + $(addprefix -I$(GECKO_INCLUDE_ROOT)/,$(required)) \ + $(AM_CPPFLAGS) + +# -DDEBUG \ +# -DXPCOM_GLUE +#-DMOZILLA_STRICT_API + +libgnomegeckoembed_0_0_la_CXXFLAGS = \ + $(GGE_DEPENDENCY_CFLAGS) \ + $(GECKO_CFLAGS) \ + $(AM_CXXFLAGS) + +libgnomegeckoembed_0_0_la_LIBADD = \ + $(GGE_DEPENDENCY_LIBS) \ + $(GECKO_LIBS) \ + $(GECKO_EXTRA_LIBS) \ + $(GECKO_GLUE_LIBS) + +libgnomegeckoembed_0_0_la_LDFLAGS = \ + $(AM_LDFLAGS) + +gnomegeckoembedincludedir = $(includedir)/gnome-gecko-embed-0.0 +gnomegeckoembedinclude_HEADERS = + +gnomegeckoembedsubincludedir = $(includedir)/gnome-gecko-embed-0.0/gecko-embed +gnomegeckoembedsubinclude_HEADERS = + +CLEANFILES = \ + $(stamp_files) \ + $(BUILT_SOURCES) \ + $(NULL) + +EXTRA_DIST = \ + gecko-embed-marshal.list \ + $(NULL) diff --git a/embed/xulrunner/src/gecko-dom-event-internal.h b/embed/xulrunner/src/gecko-dom-event-internal.h new file mode 100644 index 000000000..2d0309bd9 --- /dev/null +++ b/embed/xulrunner/src/gecko-dom-event-internal.h @@ -0,0 +1,28 @@ +/* + * Copyright © 2006 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id$ + */ + +#ifndef GECKO_DOM_EVENT_INTERNAL_H +#define GECKO_DOM_EVENT_INTERNAL_H + +class nsIDOMEvent; + +nsIDOMEvent * gecko_dom_event_get_I (GeckoDOMEvent *); + +#endif diff --git a/embed/xulrunner/src/gecko-dom-event-private.h b/embed/xulrunner/src/gecko-dom-event-private.h new file mode 100644 index 000000000..995f8cec0 --- /dev/null +++ b/embed/xulrunner/src/gecko-dom-event-private.h @@ -0,0 +1,38 @@ +/* + * Copyright © 2006 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id$ + */ + +#ifndef GECKO_DOM_EVENT_PRIVATE_H +#define GECKO_DOM_EVENT_PRIVATE_H + +struct _GeckoDOMEvent { + nsIDOMEvent *mEvent; +}; + +class nsIDOMEvent; + +#define GECKO_DOM_EVENT_STATIC_INIT(aEvent,aDOMEvent) \ +{ aEvent.mEvent = aDOMEvent; } + +#define GECKO_DOM_EVENT_STATIC_DEINIT(aEvent) \ +{ } + +GeckoDOMEvent *gecko_dom_event_new (nsIDOMEvent *); + +#endif diff --git a/embed/xulrunner/src/gecko-dom-event.cpp b/embed/xulrunner/src/gecko-dom-event.cpp new file mode 100644 index 000000000..2acdac583 --- /dev/null +++ b/embed/xulrunner/src/gecko-dom-event.cpp @@ -0,0 +1,78 @@ +/* + * Copyright © 2006 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id$ + */ + +#include <mozilla-config.h> +#include "config.h" + +#include "gecko-dom-event.h" +#include "gecko-dom-event-internal.h" +#include "gecko-dom-event-private.h" + +#include <nsIDOMEvent.h> + +/* GType implementation */ + +GType +gecko_dom_event_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + type = g_boxed_type_register_static + ("GeckoDOMEvent", + (GBoxedCopyFunc) gecko_dom_event_copy, + (GBoxedFreeFunc) gecko_dom_event_free); + } + + return type; +} + +/* Public API */ + +GeckoDOMEvent * +gecko_dom_event_new (nsIDOMEvent *aEvent) +{ + /* FIXME use slice alloc */ + GeckoDOMEvent *event = g_new (GeckoDOMEvent, 1); + + NS_ADDREF (event->mEvent = aEvent); + + return event; +} + +GeckoDOMEvent * +gecko_dom_event_copy (GeckoDOMEvent *aEvent) +{ + return gecko_dom_event_new (aEvent->mEvent); +} + +void +gecko_dom_event_free (GeckoDOMEvent *aEvent) +{ + NS_RELEASE (aEvent->mEvent); + /* FIXME slice alloc */ + g_free (aEvent); +} + +nsIDOMEvent * +gecko_dom_event_get_I (GeckoDOMEvent *aEvent) +{ + return aEvent->mEvent; +} diff --git a/embed/xulrunner/src/gecko-dom-event.h b/embed/xulrunner/src/gecko-dom-event.h new file mode 100644 index 000000000..ee1a40768 --- /dev/null +++ b/embed/xulrunner/src/gecko-dom-event.h @@ -0,0 +1,40 @@ +/* + * Copyright © 2006 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id$ + */ + +#ifndef GECKO_DOM_EVENT_H +#define GECKO_DOM_EVENT_H + +#include <glib-object.h> + +G_BEGIN_DECLS + +#define GECKO_TYPE_DOM_EVENT (gecko_dom_event_get_type ()) + +typedef struct _GeckoDOMEvent GeckoDOMEvent; + +GType gecko_dom_event_get_type (void); + +GeckoDOMEvent * gecko_dom_event_copy (GeckoDOMEvent *); + +void gecko_dom_event_free (GeckoDOMEvent *); + +G_END_DECLS + +#endif diff --git a/embed/xulrunner/src/gecko-embed-marshal.list b/embed/xulrunner/src/gecko-embed-marshal.list new file mode 100644 index 000000000..f32b027a6 --- /dev/null +++ b/embed/xulrunner/src/gecko-embed-marshal.list @@ -0,0 +1,10 @@ +BOOLEAN:BOXED +BOOLEAN:POINTER +BOOLEAN:STRING +VOID:INT,INT +VOID:INT,UINT +VOID:OBJECT,UINT +VOID:POINTER,INT,POINTER +VOID:POINTER,UINT +VOID:STRING,INT,INT +VOID:STRING,INT,UINT diff --git a/embed/xulrunner/src/gecko-embed-private.h b/embed/xulrunner/src/gecko-embed-private.h new file mode 100644 index 000000000..8f3fcae09 --- /dev/null +++ b/embed/xulrunner/src/gecko-embed-private.h @@ -0,0 +1,54 @@ +/* + * Copyright © Christopher Blizzard + * Copyright © 2006 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * --------------------------------------------------------------------------- + * Derived from Mozilla.org code, which had the following attributions: + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright © Christopher Blizzard. All Rights Reserved. + * Portions created by the Initial Developer are Copyright © 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Christopher Blizzard <blizzard@mozilla.org> + * --------------------------------------------------------------------------- + * + * $Id$ + */ + +#ifndef gecko_embed_private_h +#define gecko_embed_private_h + +#include "gecko-embed.h" + +class nsIWebBrowser; +class GeckoBrowser; + +G_BEGIN_DECLS + +extern void gecko_embed_get_nsIWebBrowser (GeckoEmbed *embed, + nsIWebBrowser **retval); + +extern GeckoBrowser* gecko_embed_get_GeckoBrowser (GeckoEmbed *embed); + + +G_END_DECLS + +#endif /* gecko_embed_private_h */ diff --git a/embed/xulrunner/src/gecko-embed-signals.h b/embed/xulrunner/src/gecko-embed-signals.h new file mode 100644 index 000000000..d5d67b351 --- /dev/null +++ b/embed/xulrunner/src/gecko-embed-signals.h @@ -0,0 +1,82 @@ +/* + * Copyright © Christopher Blizzard + * Copyright © 2006 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * --------------------------------------------------------------------------- + * Derived from Mozilla.org code, which had the following attributions: + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright © Christopher Blizzard. All Rights Reserved. + * Portions created by the Initial Developer are Copyright © 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Christopher Blizzard <blizzard@mozilla.org> + * --------------------------------------------------------------------------- + * + * $Id$ + */ + +#ifndef gecko_embed_signals_h +#define gecko_embed_signals_h + +#include <glib.h> + +G_BEGIN_DECLS + +typedef enum { + DOM_KEY_DOWN, + DOM_KEY_PRESS, + DOM_KEY_UP, + DOM_MOUSE_DOWN, + DOM_MOUSE_UP, + DOM_MOUSE_CLICK, + DOM_MOUSE_DOUBLE_CLICK, + DOM_MOUSE_OVER, + DOM_MOUSE_OUT, + DOM_ACTIVATE, + DOM_FOCUS_IN, + DOM_FOCUS_OUT, + DOM_CONTEXT_MENU, + + LINK_MESSAGE, + JS_STATUS, + LOCATION, + TITLE, + PROGRESS, + PROGRESS_ALL, + NET_STATE, + NET_STATE_ALL, + NET_START, + NET_STOP, + NEW_WINDOW, + VISIBILITY, + DESTROY_BROWSER, + OPEN_URI, + SIZE_TO, + SECURITY_CHANGE, + STATUS_CHANGE, + LAST_EMBED_SIGNAL +} GeckoEmbedSignals; + +extern guint gecko_embed_signals[LAST_EMBED_SIGNAL]; + +G_END_DECLS + +#endif /* gecko_embed_signals_h */ diff --git a/embed/xulrunner/src/gecko-embed-single-private.h b/embed/xulrunner/src/gecko-embed-single-private.h new file mode 100644 index 000000000..df2202da3 --- /dev/null +++ b/embed/xulrunner/src/gecko-embed-single-private.h @@ -0,0 +1,59 @@ +/* + * Copyright © Christopher Blizzard + * Copyright © 2006 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * --------------------------------------------------------------------------- + * Derived from Mozilla.org code, which had the following attributions: + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright © Christopher Blizzard. All Rights Reserved. + * Portions created by the Initial Developer are Copyright © 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Christopher Blizzard <blizzard@mozilla.org> + * --------------------------------------------------------------------------- + * + * $Id$ + */ + +#ifndef gecko_embed_single_private_h +#define gecko_embed_single_private_h + +#include "gecko-embed-single.h" + +class GeckoSingle; +class nsIDirectoryServiceProvider; +struct nsModuleComponentInfo; + +G_BEGIN_DECLS + +extern GeckoSingle* gecko_embed_single_get_GeckoSingle (void); + +extern void gecko_embed_single_set_directory_service_provider (nsIDirectoryServiceProvider *aProvider); + +extern void gecko_embed_single_set_app_components (const nsModuleComponentInfo *aComps, + int aNumComps); + +extern void gecko_embed_single_create_window (GeckoEmbed **aNewEmbed, + guint aChromeFlags); + +G_END_DECLS + +#endif /* gecko_embed_single_private_h */ diff --git a/embed/xulrunner/src/gecko-embed-single.cpp b/embed/xulrunner/src/gecko-embed-single.cpp new file mode 100644 index 000000000..dd147e512 --- /dev/null +++ b/embed/xulrunner/src/gecko-embed-single.cpp @@ -0,0 +1,182 @@ +/* + * Copyright © Christopher Blizzard + * Copyright © Ramiro Estrugo + * Copyright © 2006 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * --------------------------------------------------------------------------- + * Derived from Mozilla.org code, which had the following attributions: + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright © Christopher Blizzard. All Rights Reserved. + * Portions created by the Initial Developer are Copyright © 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Christopher Blizzard <blizzard@mozilla.org> + * Ramiro Estrugo <ramiro@eazel.com> + * --------------------------------------------------------------------------- + * + * $Id$ + */ + +#include <mozilla-config.h> +#include "config.h" + +#include "gecko-embed-single.h" +#include "gecko-embed-private.h" +#include "gecko-embed-signals.h" +#include "gecko-embed-marshal.h" + +#include "GeckoSingle.h" + +#define GECKO_EMBED_SINGLE_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), GECKO_TYPE_EMBED_SINGLE, GeckoEmbedSinglePrivate)) + +struct _GeckoEmbedSinglePrivate +{ + GeckoSingle *single; +}; + +enum +{ + NEW_WINDOW_ORPHAN, + LAST_SINGLE_SIGNAL +}; + +static guint gecko_embed_single_signals[LAST_SINGLE_SIGNAL] = { 0 }; + +static void gecko_embed_single_class_init (GeckoEmbedSingleClass *klass); +static void gecko_embed_single_init (GeckoEmbedSingle *embed); + +static GObjectClass *parent_class = NULL; + +GType +gecko_embed_single_get_type(void) +{ + static GType type = 0; + + if (!type) + { + const GTypeInfo info = + { + sizeof (GeckoEmbedSingleClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) gecko_embed_single_class_init, + NULL, + NULL, /* class_data */ + sizeof (GeckoEmbedSingle), + 0, /* n_preallocs */ + (GInstanceInitFunc) gecko_embed_single_init + }; + + type = g_type_register_static (G_TYPE_OBJECT, "GeckoEmbedSingle", + &info, (GTypeFlags) 0); + } + + return type; +} + +GeckoEmbedSingle * +gecko_embed_single_get (void) +{ + static GeckoEmbedSingle *single = NULL; + + if (!single) + { + single = GECKO_EMBED_SINGLE (g_object_new (GECKO_TYPE_EMBED_SINGLE, NULL)); + + g_object_add_weak_pointer (G_OBJECT (single), (gpointer *) &single); + } + + return single; +} + +extern "C" void +gecko_embed_single_create_window (GeckoEmbed **aNewEmbed, + guint aChromeFlags) +{ + GeckoEmbedSingle *single = gecko_embed_single_get (); + + *aNewEmbed = nsnull; + + if (!single) + return; + + g_signal_emit (single, gecko_embed_single_signals[NEW_WINDOW_ORPHAN], 0, + (void **) aNewEmbed, aChromeFlags); +} + +void +gecko_embed_single_push_startup(void) +{ + GeckoEmbedSingle *single = gecko_embed_single_get (); + + single->priv->single->PushStartup(); +} + +void +gecko_embed_single_pop_startup(void) +{ + GeckoEmbedSingle *single = gecko_embed_single_get (); + + single->priv->single->PopStartup(); +} + +static void +gecko_embed_single_init(GeckoEmbedSingle *embed) +{ + embed->priv = GECKO_EMBED_SINGLE_GET_PRIVATE (embed); + + embed->priv->single = new GeckoSingle (); +} + +static void +gecko_embed_single_finalize (GObject *object) +{ + GeckoEmbedSingle *single = GECKO_EMBED_SINGLE (object); + + delete single->priv->single; + single->priv->single = nsnull; + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +gecko_embed_single_class_init (GeckoEmbedSingleClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + parent_class = (GObjectClass *) g_type_class_peek_parent (klass); + + object_class->finalize = gecko_embed_single_finalize; + + gecko_embed_single_signals[NEW_WINDOW] = + g_signal_new ("new_window_orphan", + GECKO_TYPE_EMBED_SINGLE, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GeckoEmbedSingleClass, new_window_orphan), + NULL, NULL, + gecko_embed_marshal_VOID__OBJECT_UINT, + G_TYPE_NONE, + 2, + G_TYPE_OBJECT, + G_TYPE_UINT); + + g_type_class_add_private (object_class, sizeof (GeckoEmbedSinglePrivate)); +} diff --git a/embed/xulrunner/src/gecko-embed-single.h b/embed/xulrunner/src/gecko-embed-single.h new file mode 100644 index 000000000..66554f68b --- /dev/null +++ b/embed/xulrunner/src/gecko-embed-single.h @@ -0,0 +1,88 @@ +/* + * Copyright © Christopher Blizzard + * Copyright © Ramiro Estrugo + * Copyright © 2006 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * --------------------------------------------------------------------------- + * Derived from Mozilla.org code, which had the following attributions: + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright © Christopher Blizzard. All Rights Reserved. + * Portions created by the Initial Developer are Copyright © 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Christopher Blizzard <blizzard@mozilla.org> + * Ramiro Estrugo <ramiro@eazel.com> + * --------------------------------------------------------------------------- + * + * $Id$ + */ + +#ifndef gecko_embed_single_h +#define gecko_embed_single_h + +#include "gecko-embed-type-builtins.h" +#include <glib-object.h> + +G_BEGIN_DECLS + +#define GECKO_TYPE_EMBED_SINGLE (gecko_embed_single_get_type()) +#define GECKO_EMBED_SINGLE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GECKO_TYPE_EMBED_SINGLE, GeckoEmbedSingle)) +#define GECKO_EMBED_SINGLE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GECKO_TYPE_EMBED_SINGLE, GeckoEmbedSingleClass)) +#define GECKO_IS_EMBED_SINGLE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GECKO_TYPE_EMBED_SINGLE)) +#define GECKO_IS_EMBED_SINGLE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GECKO_TYPE_EMBED_SINGLE)) +#define GECKO_EMBED_SINGLE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GECKO_TYPE_EMBED_SINGLE, GeckoEmbedSingleClass)) + +typedef struct _GeckoEmbedSingle GeckoEmbedSingle; +typedef struct _GeckoEmbedSinglePrivate GeckoEmbedSinglePrivate; +typedef struct _GeckoEmbedSingleClass GeckoEmbedSingleClass; + +/* circular dependency */ +#include "gecko-embed.h" + +struct _GeckoEmbedSingle +{ + GObject parent_instance; + + /*< private >*/ + GeckoEmbedSinglePrivate *priv; +}; + +struct _GeckoEmbedSingleClass +{ + GObjectClass parent_class; + + void (* new_window_orphan) (GeckoEmbedSingle *single, + GeckoEmbed **newEmbed, + guint chromemask); +}; + +GType gecko_embed_single_get_type (void); + +GeckoEmbedSingle *gecko_embed_single_get (void); + +void gecko_embed_single_push_startup (void); + +void gecko_embed_single_pop_startup (void); + + +G_END_DECLS + +#endif /* gecko_embed_single_h */ diff --git a/embed/xulrunner/src/gecko-embed-types.h b/embed/xulrunner/src/gecko-embed-types.h new file mode 100644 index 000000000..c0cb1b71e --- /dev/null +++ b/embed/xulrunner/src/gecko-embed-types.h @@ -0,0 +1,118 @@ +/* + * Copyright © Christopher Blizzard + * Copyright © 2006 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * --------------------------------------------------------------------------- + * Derived from Mozilla.org code, which had the following attributions: + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright © Christopher Blizzard. All Rights Reserved. + * Portions created by the Initial Developer are Copyright © 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Christopher Blizzard <blizzard@mozilla.org> + * Ramiro Estrugo <ramiro@eazel.com> + * --------------------------------------------------------------------------- + * + * $Id$ + */ + +#ifndef __GECKO_EMBED_TYPES_H__ +#define __GECKO_EMBED_TYPES_H__ + +#include <glib-object.h> +#include "gecko-embed-type-builtins.h" + +G_BEGIN_DECLS + +/* These are straight out of nsIWebProgressListener.h */ + +typedef enum +{ + GECKO_EMBED_FLAG_START = 1U << 0, + GECKO_EMBED_FLAG_REDIRECTING = 1U << 1, + GECKO_EMBED_FLAG_TRANSFERRING = 1U << 2, + GECKO_EMBED_FLAG_NEGOTIATING = 1U << 3, + GECKO_EMBED_FLAG_STOP = 1U << 4, + + GECKO_EMBED_FLAG_IS_REQUEST = 1U << 16, + GECKO_EMBED_FLAG_IS_DOCUMENT = 1U << 17, + GECKO_EMBED_FLAG_IS_NETWORK = 1U << 18, + GECKO_EMBED_FLAG_IS_WINDOW = 1U << 19, + + GECKO_EMBED_FLAG_RESTORING = 1U << 24, +} GeckoEmbedProgressFlags; + +/* These are from various networking headers */ + +typedef enum +{ + /* NS_ERROR_UNKNOWN_HOST */ + GECKO_EMBED_STATUS_FAILED_DNS = 2152398878U, + /* NS_ERROR_CONNECTION_REFUSED */ + GECKO_EMBED_STATUS_FAILED_CONNECT = 2152398861U, + /* NS_ERROR_NET_TIMEOUT */ + GECKO_EMBED_STATUS_FAILED_TIMEOUT = 2152398862U, + /* NS_BINDING_ABORTED */ + GECKO_EMBED_STATUS_FAILED_USERCANCELED = 2152398850U +} GeckoEmbedStatusEnum; + +/* These used to be straight out of nsIWebNavigation.h until the API + changed. Now there's a mapping table that maps these values to the + internal values. */ + +typedef enum +{ + GECKO_EMBED_FLAG_RELOADNORMAL = 0, + GECKO_EMBED_FLAG_RELOADBYPASSCACHE = 1, + GECKO_EMBED_FLAG_RELOADBYPASSPROXY = 2, + GECKO_EMBED_FLAG_RELOADBYPASSPROXYANDCACHE = 3, + GECKO_EMBED_FLAG_RELOADCHARSETCHANGE = 4 +} GeckoEmbedReloadFlags; + +/* These are straight out of nsIWebBrowserChrome.h */ + +typedef enum +{ + GECKO_EMBED_FLAG_DEFAULTCHROME = 1U << 0, + GECKO_EMBED_FLAG_WINDOWBORDERSON = 1U << 1, + GECKO_EMBED_FLAG_WINDOWCLOSEON = 1U << 2, + GECKO_EMBED_FLAG_WINDOWRESIZEON = 1U << 3, + GECKO_EMBED_FLAG_MENUBARON = 1U << 4, + GECKO_EMBED_FLAG_TOOLBARON = 1U << 5, + GECKO_EMBED_FLAG_LOCATIONBARON = 1U << 6, + GECKO_EMBED_FLAG_STATUSBARON = 1U << 7, + GECKO_EMBED_FLAG_PERSONALTOOLBARON = 1U << 8, + GECKO_EMBED_FLAG_SCROLLBARSON = 1U << 9, + GECKO_EMBED_FLAG_TITLEBARON = 1U << 10, + GECKO_EMBED_FLAG_EXTRACHROMEON = 1U << 11, + GECKO_EMBED_FLAG_ALLCHROME = 1U << 12, + GECKO_EMBED_FLAG_WINDOWRAISED = 1U << 25, + GECKO_EMBED_FLAG_WINDOWLOWERED = 1U << 26, + GECKO_EMBED_FLAG_CENTERSCREEN = 1U << 27, + GECKO_EMBED_FLAG_DEPENDENT = 1U << 28, + GECKO_EMBED_FLAG_MODAL = 1U << 29, + GECKO_EMBED_FLAG_OPENASDIALOG = 1U << 30, + GECKO_EMBED_FLAG_OPENASCHROME = 1U << 31, +} GeckoEmbedChromeFlags; + +G_END_DECLS + +#endif /* !__GECKO_EMBED_TYPES_H__ */ diff --git a/embed/xulrunner/src/gecko-embed.cpp b/embed/xulrunner/src/gecko-embed.cpp new file mode 100644 index 000000000..1db324c44 --- /dev/null +++ b/embed/xulrunner/src/gecko-embed.cpp @@ -0,0 +1,1029 @@ +/* + * Copyright © Christopher Blizzard + * Copyright © Ramiro Estrugo + * Copyright © 2006 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * --------------------------------------------------------------------------- + * Derived from Mozilla.org code, which had the following attributions: + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright © Christopher Blizzard. All Rights Reserved. + * Portions created by the Initial Developer are Copyright © 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Christopher Blizzard <blizzard@mozilla.org> + * Ramiro Estrugo <ramiro@eazel.com> + * --------------------------------------------------------------------------- + * + * $Id$ + */ + +#include <mozilla-config.h> +#include "config.h" + +#include "gecko-embed.h" +#include "gecko-embed-private.h" +#include "gecko-embed-signals.h" +#include "gecko-embed-marshal.h" +#include "gecko-embed-single.h" +#include "gecko-embed-types.h" + +#include "gecko-dom-event.h" + +#include "GeckoBrowser.h" +#include "EmbedWindow.h" + +#ifdef XPCOM_GLUE +#include "nsXPCOMGlue.h" +#endif + +// so we can do our get_nsIWebBrowser later... +#include <nsIWebBrowser.h> + +#include <stdio.h> + +#define GET_OBJECT_CLASS_TYPE(x) G_OBJECT_CLASS_TYPE(x) + +class nsIDirectoryServiceProvider; + +// class and instance initialization + +static void gecko_embed_class_init (GeckoEmbedClass *klass); +static void gecko_embed_init (GeckoEmbed *embed); + +// GtkObject methods + +static void gecko_embed_destroy(GtkObject *object); + +// GtkWidget methods + +static void gecko_embed_realize(GtkWidget *widget); + +static void gecko_embed_unrealize(GtkWidget *widget); + +static void gecko_embed_size_allocate(GtkWidget *widget, GtkAllocation *allocation); + +static void gecko_embed_map(GtkWidget *widget); + +static void gecko_embed_unmap(GtkWidget *widget); + +#ifdef MOZ_ACCESSIBILITY_ATK +static AtkObject* gecko_embed_get_accessible (GtkWidget *widget); +#endif + +static gint handle_child_focus_in(GtkWidget *aWidget, + GdkEventFocus *aGdkFocusEvent, + GeckoEmbed *aEmbed); + +static gint handle_child_focus_out(GtkWidget *aWidget, + GdkEventFocus *aGdkFocusEvent, + GeckoEmbed *aEmbed); + +static PRInt32 sWidgetCount; + +// globals for this type of widget + +static GtkBinClass *parent_class; + +guint gecko_embed_signals[LAST_EMBED_SIGNAL] = { 0 }; + +// GtkObject + class-related functions + +#define GECKO_EMBED_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), GECKO_TYPE_EMBED, GeckoEmbedPrivate)) + +struct _GeckoEmbedPrivate +{ + GeckoBrowser *browser; +}; + +GType +gecko_embed_get_type(void) +{ + static GType type = 0; + + if (!type) + { + const GTypeInfo info = + { + sizeof (GeckoEmbedClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) gecko_embed_class_init, + NULL, + NULL, /* class_data */ + sizeof (GeckoEmbed), + 0, /* n_preallocs */ + (GInstanceInitFunc) gecko_embed_init + }; + + type = g_type_register_static (GTK_TYPE_BIN, "GeckoEmbed", + &info, (GTypeFlags) 0); + } + + return type; +} + + +/* GObject methods */ + +#define GET_BROWSER(x) (((GeckoEmbed *) x)->priv->browser) + +// FIXME split in dispose and finalize +static void +gecko_embed_destroy(GtkObject *object) +{ + GeckoEmbed *embed = GECKO_EMBED (object); + GeckoBrowser *browser = GET_BROWSER (object); + + if (browser) { + + // Destroy the widget only if it's been Init()ed. + if(browser->mMozWindowWidget != 0) { + browser->Destroy(); + } + + delete browser; + embed->priv->browser = NULL; + } + + gecko_embed_single_pop_startup(); +} + +// GtkWidget methods + +static void +gecko_embed_realize(GtkWidget *widget) +{ + GeckoEmbed *embed = GECKO_EMBED (widget); + GeckoEmbedPrivate *priv = embed->priv; + GeckoBrowser *browser = GET_BROWSER (widget); + GtkWidget *toplevel = gtk_widget_get_toplevel (widget); + GdkWindowAttr attributes; + int attributes_mask; + + GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED); + + attributes.window_type = GDK_WINDOW_CHILD; + attributes.x = widget->allocation.x; + attributes.y = widget->allocation.y; + attributes.width = widget->allocation.width; + attributes.height = widget->allocation.height; + attributes.wclass = GDK_INPUT_OUTPUT; + attributes.visual = gtk_widget_get_visual (widget); + attributes.colormap = gtk_widget_get_colormap (widget); + attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK; + + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; + + widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), + &attributes, attributes_mask); + gdk_window_set_user_data (widget->window, embed); + + widget->style = gtk_style_attach (widget->style, widget->window); + gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); + + // initialize the window + nsresult rv; + rv = browser->Init(embed); + g_return_if_fail(NS_SUCCEEDED(rv)); + + PRBool alreadyRealized = PR_FALSE; + rv = browser->Realize(&alreadyRealized); + g_return_if_fail(NS_SUCCEEDED(rv)); + + // if we're already realized we don't need to hook up to anything below + if (alreadyRealized) + return; + + browser->LoadCurrentURI(); + + GtkWidget *child_widget = GTK_BIN (widget)->child; + g_signal_connect_object (child_widget, "focus_in_event", + G_CALLBACK (handle_child_focus_in), embed, + (GConnectFlags) 0); + g_signal_connect_object (child_widget, "focus_out_event", + G_CALLBACK (handle_child_focus_out), embed, + (GConnectFlags) 0); +#if 0 + // connect to the focus out event for the child + gtk_signal_connect_while_alive(GTK_OBJECT(child_widget), + "focus_out_event", + GTK_SIGNAL_FUNC(handle_child_focus_out), + embed, + GTK_OBJECT(child_widget)); + gtk_signal_connect_while_alive(GTK_OBJECT(child_widget), + "focus_in_event", + GTK_SIGNAL_FUNC(handle_child_focus_in), + embed, + GTK_OBJECT(child_widget)); +#endif +} + +static void +gecko_embed_unrealize(GtkWidget *widget) +{ + GeckoEmbed *embed = GECKO_EMBED (widget); + GeckoEmbedPrivate *priv = embed->priv; + GeckoBrowser *browser = GET_BROWSER (widget); + GtkWidget *toplevel = gtk_widget_get_toplevel (widget); + + if (browser) { + browser->Unrealize(); + } + + if (GTK_WIDGET_CLASS(parent_class)->unrealize) + GTK_WIDGET_CLASS(parent_class)->unrealize (widget); +} + +static void +gecko_embed_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + GeckoEmbed *embed = GECKO_EMBED (widget); + GeckoBrowser *browser = GET_BROWSER (widget); + + widget->allocation = *allocation; + + if (GTK_WIDGET_REALIZED(widget)) + { + gdk_window_move_resize(widget->window, + allocation->x, allocation->y, + allocation->width, allocation->height); + + browser->Resize(allocation->width, allocation->height); + } +} + +static void +gecko_embed_map (GtkWidget *widget) +{ + GeckoEmbed *embed = GECKO_EMBED (widget); + GeckoBrowser *browser = GET_BROWSER (widget); + + GTK_WIDGET_SET_FLAGS(widget, GTK_MAPPED); + + browser->Show(); + + gdk_window_show(widget->window); + +} + +static void +gecko_embed_unmap (GtkWidget *widget) +{ + GeckoEmbed *embed = GECKO_EMBED (widget); + GeckoBrowser *browser = GET_BROWSER (widget); + + GTK_WIDGET_UNSET_FLAGS(widget, GTK_MAPPED); + + gdk_window_hide(widget->window); + + browser->Hide(); +} + +#ifdef MOZ_ACCESSIBILITY_ATK +static AtkObject* +gecko_embed_get_accessible (GtkWidget *widget) +{ + GeckoEmbed *embed = GECKO_EMBED (widget); + GeckoBrowser *browser = GET_BROWSER (widget); + + return static_cast<AtkObject *> + (browser->GetAtkObjectForCurrentDocument()); +} +#endif /* MOZ_ACCESSIBILITY_ATK */ + +static gint +handle_child_focus_in (GtkWidget *aWidget, + GdkEventFocus *aGdkFocusEvent, + GeckoEmbed *aEmbed) +{ + GeckoBrowser *browser = GET_BROWSER (aEmbed); + + browser->ChildFocusIn(); + + return FALSE; +} + +static gint +handle_child_focus_out (GtkWidget *aWidget, + GdkEventFocus *aGdkFocusEvent, + GeckoEmbed *aEmbed) +{ + GeckoBrowser *browser = GET_BROWSER (aEmbed); + + browser->ChildFocusOut(); + + return FALSE; +} + +// Widget methods + +void +gecko_embed_load_url (GeckoEmbed *embed, + const char *url) +{ + GeckoBrowser *browser; + + g_return_if_fail(embed != NULL); + g_return_if_fail(GECKO_IS_EMBED(embed)); + + browser = GET_BROWSER (embed); + + browser->SetURI(url); + + // If the widget is realized, load the URI. If it isn't then we + // will load it later. + if (GTK_WIDGET_REALIZED(embed)) + browser->LoadCurrentURI(); +} + +void +gecko_embed_stop_load (GeckoEmbed *embed) +{ + GeckoBrowser *browser; + + g_return_if_fail(GECKO_IS_EMBED(embed)); + + browser = GET_BROWSER (embed); + + if (browser->mNavigation) + browser->mNavigation->Stop(nsIWebNavigation::STOP_ALL); +} + +gboolean +gecko_embed_can_go_back (GeckoEmbed *embed) +{ + PRBool retval = PR_FALSE; + GeckoBrowser *browser; + + g_return_val_if_fail (GECKO_IS_EMBED(embed), FALSE); + + browser = GET_BROWSER (embed); + + if (browser->mNavigation) + browser->mNavigation->GetCanGoBack(&retval); + return retval; +} + +gboolean +gecko_embed_can_go_forward (GeckoEmbed *embed) +{ + PRBool retval = PR_FALSE; + GeckoBrowser *browser; + + g_return_val_if_fail (GECKO_IS_EMBED(embed), FALSE); + + browser = GET_BROWSER (embed); + + if (browser->mNavigation) + browser->mNavigation->GetCanGoForward(&retval); + return retval; +} + +void +gecko_embed_go_back (GeckoEmbed *embed) +{ + GeckoBrowser *browser; + + g_return_if_fail (GECKO_IS_EMBED(embed)); + + browser = GET_BROWSER (embed); + + if (browser->mNavigation) + browser->mNavigation->GoBack(); +} + +void +gecko_embed_go_forward (GeckoEmbed *embed) +{ + GeckoBrowser *browser; + + g_return_if_fail (GECKO_IS_EMBED(embed)); + + browser = GET_BROWSER (embed); + + if (browser->mNavigation) + browser->mNavigation->GoForward(); +} + +void +gecko_embed_render_data (GeckoEmbed *embed, const char *data, + guint32 len, const char *base_uri, + const char *mime_type) +{ + GeckoBrowser *browser; + + g_return_if_fail (GECKO_IS_EMBED(embed)); + + browser = GET_BROWSER (embed); + +#if 0 + browser->OpenStream(base_uri, mime_type); + browser->AppendToStream(data, len); + browser->CloseStream(); +#endif +} + +void +gecko_embed_open_stream (GeckoEmbed *embed, const char *base_uri, + const char *mime_type) +{ + GeckoBrowser *browser; + + g_return_if_fail (GECKO_IS_EMBED(embed)); + g_return_if_fail (GTK_WIDGET_REALIZED(GTK_WIDGET(embed))); + + browser = GET_BROWSER (embed); + +#if 0 + browser->OpenStream(base_uri, mime_type); +#endif +} + +void gecko_embed_append_data (GeckoEmbed *embed, const char *data, + guint32 len) +{ + GeckoBrowser *browser; + + g_return_if_fail (GECKO_IS_EMBED(embed)); + g_return_if_fail (GTK_WIDGET_REALIZED(GTK_WIDGET(embed))); + + browser = GET_BROWSER (embed); +#if 0 + browser->AppendToStream(data, len); +#endif +} + +void +gecko_embed_close_stream (GeckoEmbed *embed) +{ + GeckoBrowser *browser; + + g_return_if_fail (GECKO_IS_EMBED(embed)); + g_return_if_fail (GTK_WIDGET_REALIZED(GTK_WIDGET(embed))); + + browser = GET_BROWSER (embed); +#if 0 + browser->CloseStream(); +#endif +} + +char * +gecko_embed_get_link_message (GeckoEmbed *embed) +{ + char *retval = nsnull; + GeckoBrowser *browser; + nsEmbedCString tmpCString; + + g_return_val_if_fail (GECKO_IS_EMBED(embed), (char *)NULL); + + browser = GET_BROWSER (embed); + + if (browser->mWindow) { + NS_UTF16ToCString(browser->mWindow->mLinkMessage, + NS_CSTRING_ENCODING_UTF8, tmpCString); + retval = g_strdup(tmpCString.get()); + } + + return retval; +} + +char * +gecko_embed_get_js_status (GeckoEmbed *embed) +{ + char *retval = nsnull; + GeckoBrowser *browser; + nsEmbedCString tmpCString; + + g_return_val_if_fail (GECKO_IS_EMBED(embed), (char *)NULL); + + browser = GET_BROWSER (embed); + + if (browser->mWindow) { + NS_UTF16ToCString(browser->mWindow->mJSStatus, + NS_CSTRING_ENCODING_UTF8, tmpCString); + retval = g_strdup(tmpCString.get()); + } + + return retval; +} + +char * +gecko_embed_get_title (GeckoEmbed *embed) +{ + char *retval = nsnull; + GeckoBrowser *browser; + nsEmbedCString tmpCString; + + g_return_val_if_fail (GECKO_IS_EMBED(embed), (char *)NULL); + + browser = GET_BROWSER (embed); + + if (browser->mWindow) { + NS_UTF16ToCString(browser->mWindow->mTitle, + NS_CSTRING_ENCODING_UTF8, tmpCString); + retval = g_strdup(tmpCString.get()); + } + + return retval; +} + +char * +gecko_embed_get_location (GeckoEmbed *embed) +{ + char *retval = nsnull; + GeckoBrowser *browser; + + g_return_val_if_fail (GECKO_IS_EMBED(embed), (char *)NULL); + + browser = GET_BROWSER (embed); + + if (browser->mURI.Length()) { + retval = g_strdup(browser->mURI.get()); + } + + return retval; +} + +void +gecko_embed_reload (GeckoEmbed *embed, + gint32 flags) +{ + GeckoBrowser *browser; + + g_return_if_fail (GECKO_IS_EMBED(embed)); + + browser = GET_BROWSER (embed); + + PRUint32 reloadFlags = 0; + + // map the external API to the internal web navigation API. + switch (flags) { + case GECKO_EMBED_FLAG_RELOADNORMAL: + reloadFlags = 0; + break; + case GECKO_EMBED_FLAG_RELOADBYPASSCACHE: + reloadFlags = nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE; + break; + case GECKO_EMBED_FLAG_RELOADBYPASSPROXY: + reloadFlags = nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY; + break; + case GECKO_EMBED_FLAG_RELOADBYPASSPROXYANDCACHE: + reloadFlags = (nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY | + nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE); + break; + case GECKO_EMBED_FLAG_RELOADCHARSETCHANGE: + reloadFlags = nsIWebNavigation::LOAD_FLAGS_CHARSET_CHANGE; + break; + default: + reloadFlags = 0; + break; + } + + browser->Reload(reloadFlags); +} + +void +gecko_embed_set_chrome_mask (GeckoEmbed *embed, + guint32 flags) +{ + GeckoBrowser *browser; + + g_return_if_fail (GECKO_IS_EMBED(embed)); + + browser = GET_BROWSER (embed); + + browser->SetChromeMask(flags); +} + +guint32 +gecko_embed_get_chrome_mask (GeckoEmbed *embed) +{ + GeckoBrowser *browser; + + g_return_val_if_fail (GECKO_IS_EMBED(embed), 0); + + browser = GET_BROWSER (embed); + + return browser->mChromeMask; +} + +void +gecko_embed_get_nsIWebBrowser (GeckoEmbed *embed, + nsIWebBrowser **retval) +{ + GeckoBrowser *browser; + *retval = nsnull; + + g_return_if_fail (GECKO_IS_EMBED (embed)); + + browser = GET_BROWSER (embed); + + if (browser->mWindow) + browser->mWindow->GetWebBrowser(retval); +} + +GeckoBrowser * +gecko_embed_get_GeckoBrowser (GeckoEmbed *embed) +{ + g_return_val_if_fail (GECKO_IS_EMBED (embed), nsnull); + + return GET_BROWSER (embed); +} + +static void +gecko_embed_init (GeckoEmbed *embed) +{ + embed->priv = GECKO_EMBED_GET_PRIVATE (embed); + + embed->priv->browser = new GeckoBrowser(); + g_return_if_fail (embed->priv->browser); + + gtk_widget_set_name (GTK_WIDGET (embed), "gecko_embed"); + + GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(embed), GTK_NO_WINDOW); +} + +static void +gecko_embed_class_init (GeckoEmbedClass *klass) +{ + GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass); // FIXME GObject + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass); + + parent_class = (GtkBinClass *) g_type_class_peek_parent (klass); + + object_class->destroy = gecko_embed_destroy; + + widget_class->realize = gecko_embed_realize; + widget_class->unrealize = gecko_embed_unrealize; + widget_class->size_allocate = gecko_embed_size_allocate; + widget_class->map = gecko_embed_map; + widget_class->unmap = gecko_embed_unmap; + +#ifdef MOZ_ACCESSIBILITY_ATK + widget_class->get_accessible = gecko_embed_get_accessible; +#endif + + GType dom_param_types[1] = { GECKO_TYPE_DOM_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE }; + + gecko_embed_signals[DOM_KEY_DOWN] = + g_signal_newv ("dom-key-down", + GECKO_TYPE_EMBED, + (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST), + NULL, + g_signal_accumulator_true_handled, NULL, + gecko_embed_marshal_BOOLEAN__BOXED, + G_TYPE_BOOLEAN, + G_N_ELEMENTS (dom_param_types), + dom_param_types); + + gecko_embed_signals[DOM_KEY_PRESS] = + g_signal_newv ("dom-key-press", + GECKO_TYPE_EMBED, + (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST), + NULL, + g_signal_accumulator_true_handled, NULL, + gecko_embed_marshal_BOOLEAN__BOXED, + G_TYPE_BOOLEAN, + G_N_ELEMENTS (dom_param_types), + dom_param_types); + + gecko_embed_signals[DOM_KEY_UP] = + g_signal_newv ("dom-key-up", + GECKO_TYPE_EMBED, + (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST), + NULL, + g_signal_accumulator_true_handled, NULL, + gecko_embed_marshal_BOOLEAN__BOXED, + G_TYPE_BOOLEAN, + G_N_ELEMENTS (dom_param_types), + dom_param_types); + + gecko_embed_signals[DOM_MOUSE_DOWN] = + g_signal_newv ("dom-mouse-down", + GECKO_TYPE_EMBED, + (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST), + NULL, + g_signal_accumulator_true_handled, NULL, + gecko_embed_marshal_BOOLEAN__BOXED, + G_TYPE_BOOLEAN, + G_N_ELEMENTS (dom_param_types), + dom_param_types); + + gecko_embed_signals[DOM_MOUSE_UP] = + g_signal_newv ("dom-mouse-up", + GECKO_TYPE_EMBED, + (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST), + NULL, + g_signal_accumulator_true_handled, NULL, + gecko_embed_marshal_BOOLEAN__BOXED, + G_TYPE_BOOLEAN, + G_N_ELEMENTS (dom_param_types), + dom_param_types); + + gecko_embed_signals[DOM_MOUSE_CLICK] = + g_signal_newv ("dom-mouse-click", + GECKO_TYPE_EMBED, + (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST), + NULL, + g_signal_accumulator_true_handled, NULL, + gecko_embed_marshal_BOOLEAN__BOXED, + G_TYPE_BOOLEAN, + G_N_ELEMENTS (dom_param_types), + dom_param_types); + + gecko_embed_signals[DOM_MOUSE_DOUBLE_CLICK] = + g_signal_newv ("dom-mouse-dbl-click", + GECKO_TYPE_EMBED, + (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST), + NULL, + g_signal_accumulator_true_handled, NULL, + gecko_embed_marshal_BOOLEAN__BOXED, + G_TYPE_BOOLEAN, + G_N_ELEMENTS (dom_param_types), + dom_param_types); + + gecko_embed_signals[DOM_MOUSE_OVER] = + g_signal_newv ("dom-mouse-over", + GECKO_TYPE_EMBED, + (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST), + NULL, + g_signal_accumulator_true_handled, NULL, + gecko_embed_marshal_BOOLEAN__BOXED, + G_TYPE_BOOLEAN, + G_N_ELEMENTS (dom_param_types), + dom_param_types); + + gecko_embed_signals[DOM_MOUSE_OUT] = + g_signal_newv ("dom-mouse-out", + GECKO_TYPE_EMBED, + (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST), + NULL, + g_signal_accumulator_true_handled, NULL, + gecko_embed_marshal_BOOLEAN__BOXED, + G_TYPE_BOOLEAN, + G_N_ELEMENTS (dom_param_types), + dom_param_types); + + gecko_embed_signals[DOM_MOUSE_OUT] = + g_signal_newv ("dom-focus-in", + GECKO_TYPE_EMBED, + (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST), + NULL, + g_signal_accumulator_true_handled, NULL, + gecko_embed_marshal_BOOLEAN__BOXED, + G_TYPE_BOOLEAN, + G_N_ELEMENTS (dom_param_types), + dom_param_types); + + gecko_embed_signals[DOM_MOUSE_OUT] = + g_signal_newv ("dom-focus-out", + GECKO_TYPE_EMBED, + (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST), + NULL, + g_signal_accumulator_true_handled, NULL, + gecko_embed_marshal_BOOLEAN__BOXED, + G_TYPE_BOOLEAN, + G_N_ELEMENTS (dom_param_types), + dom_param_types); + + gecko_embed_signals[DOM_MOUSE_OUT] = + g_signal_newv ("dom-activate", + GECKO_TYPE_EMBED, + (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST), + NULL, + g_signal_accumulator_true_handled, NULL, + gecko_embed_marshal_BOOLEAN__BOXED, + G_TYPE_BOOLEAN, + G_N_ELEMENTS (dom_param_types), + dom_param_types); + + gecko_embed_signals[DOM_CONTEXT_MENU] = + g_signal_newv ("dom-context-menu", + GECKO_TYPE_EMBED, + (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST), + NULL, + g_signal_accumulator_true_handled, NULL, + gecko_embed_marshal_BOOLEAN__BOXED, + G_TYPE_BOOLEAN, + G_N_ELEMENTS (dom_param_types), + dom_param_types); + + gecko_embed_signals[OPEN_URI] = + g_signal_new ("open_uri", + GECKO_TYPE_EMBED, + (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST), + G_STRUCT_OFFSET (GeckoEmbedClass, open_uri), + g_signal_accumulator_true_handled, NULL, + gecko_embed_marshal_BOOLEAN__STRING, + G_TYPE_BOOLEAN, + 1, + G_TYPE_STRING); + + gecko_embed_signals[NET_START] = + g_signal_new ("net_start", + GECKO_TYPE_EMBED, + (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST), + G_STRUCT_OFFSET (GeckoEmbedClass, net_start), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + gecko_embed_signals[NET_STOP] = + g_signal_new ("net_stop", + GECKO_TYPE_EMBED, + (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST), + G_STRUCT_OFFSET (GeckoEmbedClass, net_stop), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + gecko_embed_signals[NET_STATE] = + g_signal_new ("net_state", + GECKO_TYPE_EMBED, + (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST), + G_STRUCT_OFFSET (GeckoEmbedClass, net_state), + NULL, NULL, + gecko_embed_marshal_VOID__INT_UINT, + G_TYPE_NONE, + 2, + G_TYPE_INT, + G_TYPE_UINT); + + gecko_embed_signals[NET_STATE_ALL] = + g_signal_new ("net_state_all", + GECKO_TYPE_EMBED, + (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST), + G_STRUCT_OFFSET (GeckoEmbedClass, net_state_all), + NULL, NULL, + gecko_embed_marshal_VOID__STRING_INT_UINT, + G_TYPE_NONE, + 3, + G_TYPE_STRING, + G_TYPE_INT, + G_TYPE_UINT); // static scope? to avoid string copy? or G_TYPE_POINTER as 1st? + + gecko_embed_signals[PROGRESS] = + g_signal_new ("progress", + GECKO_TYPE_EMBED, + (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST), + G_STRUCT_OFFSET (GeckoEmbedClass, progress), + NULL, NULL, + gecko_embed_marshal_VOID__INT_INT, + G_TYPE_NONE, + 2, + G_TYPE_INT, + G_TYPE_INT); + + gecko_embed_signals[PROGRESS_ALL] = + g_signal_new ("progress_all", + GECKO_TYPE_EMBED, + (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST), + G_STRUCT_OFFSET (GeckoEmbedClass, progress_all), + NULL, NULL, + gecko_embed_marshal_VOID__STRING_INT_INT, + G_TYPE_NONE, + 3, + G_TYPE_STRING, + G_TYPE_INT, + G_TYPE_INT); // static scope? + + gecko_embed_signals[SECURITY_CHANGE] = + g_signal_new ("security_change", + GECKO_TYPE_EMBED, + (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST), + G_STRUCT_OFFSET (GeckoEmbedClass, security_change), + NULL, NULL, + gecko_embed_marshal_VOID__POINTER_UINT, + G_TYPE_NONE, + 2, + G_TYPE_POINTER, + G_TYPE_UINT); + + gecko_embed_signals[STATUS_CHANGE] = + g_signal_new ("status_change", + GECKO_TYPE_EMBED, + (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST), + G_STRUCT_OFFSET (GeckoEmbedClass, status_change), + NULL, NULL, + gecko_embed_marshal_VOID__POINTER_INT_POINTER, + G_TYPE_NONE, + 3, + G_TYPE_POINTER, + G_TYPE_INT, + G_TYPE_POINTER); + + gecko_embed_signals[LINK_MESSAGE] = + g_signal_new ("link_message", + GECKO_TYPE_EMBED, + (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST), + G_STRUCT_OFFSET (GeckoEmbedClass, link_message), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + gecko_embed_signals[JS_STATUS] = + g_signal_new ("js_status", + GECKO_TYPE_EMBED, + (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST), + G_STRUCT_OFFSET (GeckoEmbedClass, js_status_message), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + gecko_embed_signals[LOCATION] = + g_signal_new ("location", + GECKO_TYPE_EMBED, + (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST), + G_STRUCT_OFFSET (GeckoEmbedClass, location), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + gecko_embed_signals[TITLE] = + g_signal_new ("title", + GECKO_TYPE_EMBED, + (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST), + G_STRUCT_OFFSET (GeckoEmbedClass, title), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + gecko_embed_signals[VISIBILITY] = + g_signal_new ("visibility", + GECKO_TYPE_EMBED, + (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST), + G_STRUCT_OFFSET (GeckoEmbedClass, visibility), + NULL, NULL, + g_cclosure_marshal_VOID__BOOLEAN, + G_TYPE_NONE, + 1, + G_TYPE_BOOLEAN); + + gecko_embed_signals[DESTROY_BROWSER] = + g_signal_new ("destroy_browser", + GECKO_TYPE_EMBED, + (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST), + G_STRUCT_OFFSET (GeckoEmbedClass, destroy_browser), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + gecko_embed_signals[SIZE_TO] = + g_signal_new ("size_to", + GECKO_TYPE_EMBED, + (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST), + G_STRUCT_OFFSET (GeckoEmbedClass, size_to), + NULL, NULL, + gecko_embed_marshal_VOID__INT_INT, + G_TYPE_NONE, + 2, + G_TYPE_INT, + G_TYPE_INT); + + gecko_embed_signals[NEW_WINDOW] = + g_signal_new ("new_window", + GECKO_TYPE_EMBED, + (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST), + G_STRUCT_OFFSET (GeckoEmbedClass, new_window), + NULL, NULL, + gecko_embed_marshal_VOID__OBJECT_UINT, + G_TYPE_NONE, + 2, + G_TYPE_OBJECT, + G_TYPE_UINT); + + g_type_class_add_private (object_class, sizeof (GeckoEmbedPrivate)); +} + +GtkWidget * +gecko_embed_new (void) +{ + return GTK_WIDGET (g_object_new (GECKO_TYPE_EMBED, NULL)); +} diff --git a/embed/xulrunner/src/gecko-embed.h b/embed/xulrunner/src/gecko-embed.h new file mode 100644 index 000000000..8aec90bc2 --- /dev/null +++ b/embed/xulrunner/src/gecko-embed.h @@ -0,0 +1,151 @@ +/* + * Copyright © Christopher Blizzard + * Copyright © Ramiro Estrugo + * Copyright © 2006 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * --------------------------------------------------------------------------- + * Derived from Mozilla.org code, which had the following attributions: + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright © Christopher Blizzard. All Rights Reserved. + * Portions created by the Initial Developer are Copyright © 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Christopher Blizzard <blizzard@mozilla.org> + * Ramiro Estrugo <ramiro@eazel.com> + * --------------------------------------------------------------------------- + * + * $Id$ + */ + +#ifndef gecko_embed_h +#define gecko_embed_h + +#include <stddef.h> +#include <gtk/gtk.h> + +G_BEGIN_DECLS + +#define GECKO_TYPE_EMBED (gecko_embed_get_type()) +#define GECKO_EMBED(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GECKO_TYPE_EMBED, GeckoEmbed)) +#define GECKO_EMBED_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GECKO_TYPE_EMBED, GeckoEmbedClass)) +#define GECKO_IS_EMBED(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GECKO_TYPE_EMBED)) +#define GECKO_IS_EMBED_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GECKO_TYPE_EMBED)) +#define GECKO_EMBED_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GECKO_TYPE_EMBED, GeckoEmbedClass)) + +typedef struct _GeckoEmbed GeckoEmbed; +typedef struct _GeckoEmbedPrivate GeckoEmbedPrivate; +typedef struct _GeckoEmbedClass GeckoEmbedClass; + +struct _GeckoEmbed +{ + GtkBin parent_instance; + + /*< private >*/ + GeckoEmbedPrivate *priv; +}; + +struct _GeckoEmbedClass +{ + GtkBinClass parent_class; + + /* Signals */ + + /* Network */ + gboolean (* open_uri) (GeckoEmbed *embed, const char *aURI); + void (* net_start) (GeckoEmbed *embed); + void (* net_stop) (GeckoEmbed *embed); + void (* net_state) (GeckoEmbed *embed, int state, guint status); + void (* net_state_all) (GeckoEmbed *embed, const char *aURI, + int state, guint status); + void (* progress) (GeckoEmbed *embed, int curprogress, + int maxprogress); + void (* progress_all) (GeckoEmbed *embed, const char *aURI, + int curprogress, int maxprogress); + void (* security_change) (GeckoEmbed *embed, gpointer request, + guint state); + void (* status_change) (GeckoEmbed *embed, gpointer request, + int status, gpointer message); + + /* Document */ + void (* link_message) (GeckoEmbed *embed); + void (* js_status_message) (GeckoEmbed *embed); + void (* location) (GeckoEmbed *embed); + void (* title) (GeckoEmbed *embed); + void (* visibility) (GeckoEmbed *embed, gboolean visibility); + void (* destroy_browser) (GeckoEmbed *embed); + void (* size_to) (GeckoEmbed *embed, int width, int height); + + + /* misc. */ + void (* new_window) (GeckoEmbed *embed, GeckoEmbed **newEmbed, + guint chromemask); + + /* reserved for future use */ + void (* reserved_0) (void); + void (* reserved_1) (void); + void (* reserved_2) (void); + void (* reserved_3) (void); + void (* reserved_4) (void); + void (* reserved_5) (void); + void (* reserved_6) (void); + void (* reserved_7) (void); + void (* reserved_8) (void); + void (* reserved_9) (void); + void (* reserved_a) (void); + void (* reserved_b) (void); + void (* reserved_c) (void); + void (* reserved_d) (void); + void (* reserved_e) (void); + void (* reserved_f) (void); +}; + +GType gecko_embed_get_type (void); +GtkWidget *gecko_embed_new (void); +void gecko_embed_load_url (GeckoEmbed *embed, + const char *url); +void gecko_embed_stop_load (GeckoEmbed *embed); +gboolean gecko_embed_can_go_back (GeckoEmbed *embed); +gboolean gecko_embed_can_go_forward (GeckoEmbed *embed); +void gecko_embed_go_back (GeckoEmbed *embed); +void gecko_embed_go_forward (GeckoEmbed *embed); +void gecko_embed_render_data (GeckoEmbed *embed, + const char *data, + guint32 len, + const char *base_uri, + const char *mime_type); +void gecko_embed_open_stream (GeckoEmbed *embed, + const char *base_uri, + const char *mime_type); +void gecko_embed_append_data (GeckoEmbed *embed, + const char *data, guint32 len); +void gecko_embed_close_stream (GeckoEmbed *embed); +char *gecko_embed_get_link_message (GeckoEmbed *embed); +char *gecko_embed_get_js_status (GeckoEmbed *embed); +char *gecko_embed_get_title (GeckoEmbed *embed); +char *gecko_embed_get_location (GeckoEmbed *embed); +void gecko_embed_reload (GeckoEmbed *embed, gint32 flags); +void gecko_embed_set_chrome_mask (GeckoEmbed *embed, + guint32 flags); +guint32 gecko_embed_get_chrome_mask (GeckoEmbed *embed); + +G_END_DECLS + +#endif /* gecko_embed_h */ diff --git a/embed/xulrunner/src/gecko-init-internal.h b/embed/xulrunner/src/gecko-init-internal.h new file mode 100644 index 000000000..551b4bd45 --- /dev/null +++ b/embed/xulrunner/src/gecko-init-internal.h @@ -0,0 +1,30 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Copyright © 2006 Xan Lopez <xan@gnome.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * $Id$ + * ***** END LICENSE BLOCK ***** */ + +#ifndef __gecko_init_internal_h +#define __gecko_init_internal_h + +#include <gtk/gtk.h> +#include "nsIDirectoryService.h" + +extern gboolean gecko_init_with_params (const char *, const char*, const char*, nsIDirectoryServiceProvider*); + +#endif diff --git a/embed/xulrunner/src/gecko-init-private.h b/embed/xulrunner/src/gecko-init-private.h new file mode 100644 index 000000000..b4cc34bfb --- /dev/null +++ b/embed/xulrunner/src/gecko-init-private.h @@ -0,0 +1,33 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Copyright © 2006 Xan Lopez <xan@gnome.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * $Id$ + * ***** END LICENSE BLOCK ***** */ + +#ifndef __gecko_init_private_h +#define __gecko_init_private_h + +#include <gtk/gtk.h> + +G_BEGIN_DECLS + +void gecko_reparent_to_offscreen (GtkWidget*); + +G_END_DECLS + +#endif diff --git a/embed/xulrunner/src/gecko-init.cpp b/embed/xulrunner/src/gecko-init.cpp new file mode 100644 index 000000000..cbad02a67 --- /dev/null +++ b/embed/xulrunner/src/gecko-init.cpp @@ -0,0 +1,392 @@ +/* + * Copyright © Christopher Blizzard + * Copyright © 2006 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * --------------------------------------------------------------------------- + * Derived from Mozilla.org code, which had the following attributions: + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright © Christopher Blizzard. All Rights Reserved. + * Portions created by the Initial Developer are Copyright © 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Christopher Blizzard <blizzard@mozilla.org> + * --------------------------------------------------------------------------- + * + * $Id$ + */ + +#include <mozilla-config.h> +#include <config.h> + +#include <stdlib.h> + +#include "GeckoSingle.h" + +#include "nsIDocShell.h" +#include "nsIWebProgress.h" +#include "nsIWebBrowserStream.h" +#include "nsIWidget.h" +#include "nsIDirectoryService.h" +#include "nsAppDirectoryServiceDefs.h" + +// for NS_APPSHELL_CID +#include "nsWidgetsCID.h" + +// for do_GetInterface +#include "nsIInterfaceRequestor.h" +// for do_CreateInstance +#include "nsIComponentManager.h" + +// for initializing our window watcher service +#include "nsIWindowWatcher.h" + +#include "nsILocalFile.h" +#include "nsXULAppAPI.h" + +// all of the crap that we need for event listeners +// and when chrome windows finish loading +#include "nsIDOMWindow.h" +#include "nsPIDOMWindow.h" +#include "nsIDOMWindowInternal.h" + +// For seting scrollbar visibilty +#include <nsIDOMBarProp.h> + +// for the focus hacking we need to do +#include "nsIFocusController.h" + +// app component registration +#include "nsIGenericFactory.h" +#include "nsIComponentRegistrar.h" + +// all of our local includes +#include "gecko-init.h" +#include "GeckoSingle.h" +#include "EmbedWindow.h" +#include "EmbedProgress.h" +#include "EmbedContentListener.h" +#include "EmbedEventListener.h" +#include "EmbedWindowCreator.h" +#include "GeckoPromptService.h" + +#ifdef MOZ_ACCESSIBILITY_ATK +#include "nsIAccessibilityService.h" +#include "nsIAccessible.h" +#include "nsIDOMDocument.h" +#endif + +#include <nsServiceManagerUtils.h> +#include "nsXPCOMGlue.h" + +#include "gecko-init.h" +#include "gecko-init-private.h" +#include "gecko-init-internal.h" + +NS_GENERIC_FACTORY_CONSTRUCTOR(GeckoPromptService) + +static const nsModuleComponentInfo defaultAppComps[] = { + { + GECKO_PROMPT_SERVICE_CLASSNAME, + GECKO_PROMPT_SERVICE_CID, + "@mozilla.org/embedcomp/prompt-service;1", + GeckoPromptServiceConstructor + }, +#ifdef HAVE_NSINONBLOCKINGALERTSERVICE_H + { + GECKO_PROMPT_SERVICE_CLASSNAME, + GECKO_PROMPT_SERVICE_CID, + "@mozilla.org/embedcomp/nbalert-service;1", + GeckoPromptServiceConstructor + }, +#endif /* HAVE_NSINONBLOCKINGALERTSERVICE_H */ +}; + +GtkWidget *sOffscreenWindow = 0; +GtkWidget *sOffscreenFixed = 0; +const nsModuleComponentInfo *sAppComps = defaultAppComps; +int sNumAppComps = sizeof (defaultAppComps) / sizeof (nsModuleComponentInfo); +nsILocalFile *sProfileDir = nsnull; +nsISupports *sProfileLock = nsnull; +nsIDirectoryServiceProvider* sAppFileLocProvider; + +class GTKEmbedDirectoryProvider : public nsIDirectoryServiceProvider2 +{ + public: + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_NSIDIRECTORYSERVICEPROVIDER + NS_DECL_NSIDIRECTORYSERVICEPROVIDER2 +}; + +static const GTKEmbedDirectoryProvider kDirectoryProvider; + +NS_IMPL_QUERY_INTERFACE2(GTKEmbedDirectoryProvider, + nsIDirectoryServiceProvider, + nsIDirectoryServiceProvider2) + +NS_IMETHODIMP_(nsrefcnt) +GTKEmbedDirectoryProvider::AddRef() +{ + return 2; +} + +NS_IMETHODIMP_(nsrefcnt) +GTKEmbedDirectoryProvider::Release() +{ + return 1; +} + +NS_IMETHODIMP +GTKEmbedDirectoryProvider::GetFile(const char *aKey, PRBool *aPersist, + nsIFile* *aResult) +{ + if (sAppFileLocProvider) { + nsresult rv = sAppFileLocProvider->GetFile(aKey, aPersist, + aResult); + if (NS_SUCCEEDED(rv)) + return rv; + } + + if (sProfileDir && !strcmp(aKey, NS_APP_USER_PROFILE_50_DIR)) { + *aPersist = PR_TRUE; + return sProfileDir->Clone(aResult); + } + + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +GTKEmbedDirectoryProvider::GetFiles(const char *aKey, + nsISimpleEnumerator* *aResult) +{ + nsCOMPtr<nsIDirectoryServiceProvider2> + dp2(do_QueryInterface(sAppFileLocProvider)); + + if (!dp2) + return NS_ERROR_FAILURE; + + return dp2->GetFiles(aKey, aResult); +} + +/* static */ +nsresult +RegisterAppComponents(void) +{ + nsCOMPtr<nsIComponentRegistrar> cr; + nsresult rv = NS_GetComponentRegistrar(getter_AddRefs(cr)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr<nsIComponentManager> cm; + rv = NS_GetComponentManager (getter_AddRefs (cm)); + NS_ENSURE_SUCCESS (rv, rv); + + for (int i = 0; i < sNumAppComps; ++i) { + nsCOMPtr<nsIGenericFactory> componentFactory; + rv = NS_NewGenericFactory(getter_AddRefs(componentFactory), + &(sAppComps[i])); + if (NS_FAILED(rv)) { + NS_WARNING("Unable to create factory for component"); + continue; // don't abort registering other components + } + + rv = cr->RegisterFactory(sAppComps[i].mCID, sAppComps[i].mDescription, + sAppComps[i].mContractID, componentFactory); + NS_ASSERTION(NS_SUCCEEDED(rv), "Unable to register factory for component"); + + // Call the registration hook of the component, if any + if (sAppComps[i].mRegisterSelfProc) { + rv = sAppComps[i].mRegisterSelfProc(cm, nsnull, nsnull, nsnull, + &(sAppComps[i])); + NS_ASSERTION(NS_SUCCEEDED(rv), "Unable to self-register component"); + } + } + + return rv; +} + +/* static */ +nsresult +StartupProfile (const char* aProfileDir, const char* aProfileName) +{ + /* Running without profile */ + if (!aProfileDir || !aProfileName) + return NS_OK; + + if (sProfileDir && GeckoSingle::sWidgetCount != 0) { + NS_ERROR("Cannot change profile directory during run!"); + return NS_ERROR_ALREADY_INITIALIZED; + } + + nsresult rv; + nsCOMPtr<nsILocalFile> profileDir; + rv = NS_NewNativeLocalFile (nsDependentCString (aProfileDir), PR_TRUE, + &sProfileDir); + if (NS_FAILED (rv)) + return rv; + + if (aProfileName) { + rv = sProfileDir->AppendNative (nsDependentCString (aProfileName)); + if (NS_FAILED (rv)) + return rv; // FIXMEchpe release sProfileDir + } + + rv = XRE_LockProfileDirectory (sProfileDir, &sProfileLock); + if (NS_FAILED (rv)) + return rv; // FIXMEchpe release sProfileDir + + if (GeckoSingle::sWidgetCount) + XRE_NotifyProfile(); + + return NS_OK; +} + +gboolean +gecko_init () +{ + return gecko_init_with_params (nsnull, nsnull, nsnull, nsnull); +} + +gboolean +gecko_init_with_profile (const char *aGREPath, + const char* aProfileDir, + const char* aProfileName) +{ + return gecko_init_with_params (aGREPath, aProfileDir, aProfileName, nsnull); +} + +gboolean +gecko_init_with_params (const char *aGREPath, + const char* aProfileDir, + const char* aProfileName, + nsIDirectoryServiceProvider* aAppFileLocProvider) +{ + nsresult rv; + nsCOMPtr<nsILocalFile> binDir; + +#if 0 //def XPCOM_GLUE + const char* xpcomLocation = GRE_GetXPCOMPath(); + + // Startup the XPCOM Glue that links us up with XPCOM. + nsresult rv = XPCOMGlueStartup(xpcomLocation); + if (NS_FAILED(rv)) return; +#endif + + NS_IF_ADDREF (sAppFileLocProvider = aAppFileLocProvider); + + /* FIrst try to lock the profile */ + rv = StartupProfile (aProfileDir, aProfileName); + if (NS_FAILED (rv)) + return FALSE; + + const char* aCompPath = g_getenv("GECKO_HOME"); + + if (aCompPath) { + rv = NS_NewNativeLocalFile(nsEmbedCString(aCompPath), PR_TRUE, getter_AddRefs(binDir)); + NS_ENSURE_SUCCESS(rv,false); + } + + if (!aGREPath) + aGREPath = getenv("MOZILLA_FIVE_HOME"); + + if (!aGREPath) + return FALSE; + + nsCOMPtr<nsILocalFile> greDir; + rv = NS_NewNativeLocalFile (nsDependentCString (aGREPath), PR_TRUE, + getter_AddRefs (greDir)); + if (NS_FAILED(rv)) + return FALSE; + + rv = XRE_InitEmbedding(greDir, binDir, + const_cast<GTKEmbedDirectoryProvider*> (&kDirectoryProvider), + nsnull, nsnull); + if (NS_FAILED (rv)) + return FALSE; + + if (sProfileDir) + XRE_NotifyProfile(); + + rv = RegisterAppComponents(); + NS_ASSERTION(NS_SUCCEEDED(rv), "Warning: Failed to register app components.\n"); + + // create our local object + EmbedWindowCreator *creator = new EmbedWindowCreator(); + nsCOMPtr<nsIWindowCreator> windowCreator = + static_cast<nsIWindowCreator *>(creator); + + // Attach it via the watcher service + nsCOMPtr<nsIWindowWatcher> watcher (do_GetService(NS_WINDOWWATCHER_CONTRACTID)); + if (watcher) + watcher->SetWindowCreator(windowCreator); + + return true; +} + +/* static */ +void +EnsureOffscreenWindow(void) +{ + if (sOffscreenWindow) + return; + + sOffscreenWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_widget_realize (sOffscreenWindow); + sOffscreenFixed = gtk_fixed_new(); + gtk_container_add (GTK_CONTAINER (sOffscreenWindow), sOffscreenFixed); + gtk_widget_realize (sOffscreenFixed); +} + +/* static */ +void +gecko_reparent_to_offscreen(GtkWidget *aWidget) +{ + EnsureOffscreenWindow(); + + gtk_widget_reparent(aWidget, sOffscreenFixed); +} + +/* static */ +void +DestroyOffscreenWindow(void) +{ + if (!sOffscreenWindow) + return; + gtk_widget_destroy(sOffscreenWindow); + sOffscreenWindow = nsnull; + sOffscreenFixed = nsnull; +} + +void +gecko_shutdown() +{ + // destroy the offscreen window + DestroyOffscreenWindow(); + + NS_IF_RELEASE (sProfileDir); + + // shut down XPCOM/Embedding + XRE_TermEmbedding(); + + // we no longer need a reference to the DirectoryServiceProvider + NS_IF_RELEASE (sAppFileLocProvider); + + /* FIXMchpe before or after TermEmbedding?? */ + NS_IF_RELEASE (sProfileLock); +} diff --git a/embed/xulrunner/src/gecko-init.h b/embed/xulrunner/src/gecko-init.h new file mode 100644 index 000000000..ee66f0ea4 --- /dev/null +++ b/embed/xulrunner/src/gecko-init.h @@ -0,0 +1,35 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Copyright © 2006 Xan Lopez <xan@gnome.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * $Id$ + * ***** END LICENSE BLOCK ***** */ + +#ifndef __gecko_init_h +#define __gecko_init_h + +#include <gtk/gtk.h> + +G_BEGIN_DECLS + +gboolean gecko_init (); +gboolean gecko_init_with_profile (const char *, const char*, const char*); +void gecko_shutdown (); + +G_END_DECLS + +#endif |