aboutsummaryrefslogtreecommitdiffstats
path: root/embed/xulrunner/src
diff options
context:
space:
mode:
authorChristian Persch <chpe@src.gnome.org>2007-08-26 04:59:04 +0800
committerChristian Persch <chpe@src.gnome.org>2007-08-26 04:59:04 +0800
commit6deabce61b1758b0c395678bf5c2769ee4ca17c6 (patch)
tree27866c89b34cb0fe866753fbef2894e6dfd01785 /embed/xulrunner/src
parentd2bc7076ca31996d4a5b80b74e4380e6f2f56321 (diff)
downloadgsoc2013-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')
-rw-r--r--embed/xulrunner/src/AutoJSContextStack.cpp48
-rw-r--r--embed/xulrunner/src/AutoJSContextStack.h41
-rw-r--r--embed/xulrunner/src/AutoWindowModalState.cpp43
-rw-r--r--embed/xulrunner/src/AutoWindowModalState.h38
-rw-r--r--embed/xulrunner/src/EmbedContentListener.cpp159
-rw-r--r--embed/xulrunner/src/EmbedContentListener.h63
-rw-r--r--embed/xulrunner/src/EmbedEventListener.cpp183
-rw-r--r--embed/xulrunner/src/EmbedEventListener.h102
-rw-r--r--embed/xulrunner/src/EmbedProgress.cpp224
-rw-r--r--embed/xulrunner/src/EmbedProgress.h63
-rw-r--r--embed/xulrunner/src/EmbedStream.cpp311
-rw-r--r--embed/xulrunner/src/EmbedStream.h79
-rw-r--r--embed/xulrunner/src/EmbedWindow.cpp467
-rw-r--r--embed/xulrunner/src/EmbedWindow.h97
-rw-r--r--embed/xulrunner/src/EmbedWindowCreator.cpp108
-rw-r--r--embed/xulrunner/src/EmbedWindowCreator.h51
-rw-r--r--embed/xulrunner/src/GeckoBrowser.cpp676
-rw-r--r--embed/xulrunner/src/GeckoBrowser.h159
-rw-r--r--embed/xulrunner/src/GeckoPromptService.cpp891
-rw-r--r--embed/xulrunner/src/GeckoPromptService.h53
-rw-r--r--embed/xulrunner/src/GeckoSingle.cpp122
-rw-r--r--embed/xulrunner/src/GeckoSingle.h97
-rw-r--r--embed/xulrunner/src/GeckoUtils.cpp87
-rw-r--r--embed/xulrunner/src/GeckoUtils.h34
-rw-r--r--embed/xulrunner/src/Makefile.am167
-rw-r--r--embed/xulrunner/src/gecko-dom-event-internal.h28
-rw-r--r--embed/xulrunner/src/gecko-dom-event-private.h38
-rw-r--r--embed/xulrunner/src/gecko-dom-event.cpp78
-rw-r--r--embed/xulrunner/src/gecko-dom-event.h40
-rw-r--r--embed/xulrunner/src/gecko-embed-marshal.list10
-rw-r--r--embed/xulrunner/src/gecko-embed-private.h54
-rw-r--r--embed/xulrunner/src/gecko-embed-signals.h82
-rw-r--r--embed/xulrunner/src/gecko-embed-single-private.h59
-rw-r--r--embed/xulrunner/src/gecko-embed-single.cpp182
-rw-r--r--embed/xulrunner/src/gecko-embed-single.h88
-rw-r--r--embed/xulrunner/src/gecko-embed-types.h118
-rw-r--r--embed/xulrunner/src/gecko-embed.cpp1029
-rw-r--r--embed/xulrunner/src/gecko-embed.h151
-rw-r--r--embed/xulrunner/src/gecko-init-internal.h30
-rw-r--r--embed/xulrunner/src/gecko-init-private.h33
-rw-r--r--embed/xulrunner/src/gecko-init.cpp392
-rw-r--r--embed/xulrunner/src/gecko-init.h35
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