2011-08-15 Ginn Chen <[email protected]> gnome-2-30
authorginnchen
Mon, 15 Aug 2011 02:22:00 +0000
branchgnome-2-30
changeset 22060 e73e586f0b48
parent 22059 97a4cfa2c5b2
child 22061 d9037d590c7d
2011-08-15 Ginn Chen <[email protected]> * base-specs/firefox.spec: Update Firefox to 6.0 (CR7069155). * ext-sources/firefox-js.pc.in: * ext-sources/firefox-plugin.pc.in: * ext-sources/firefox-xpcom.pc.in: * ext-sources/firefox60-profile-sparc-ss12-2.tar.bz2: * ext-sources/firefox60-profile-x86-ss12-2.tar.bz2: * patches/devhelp-02-gecko20.diff: * patches/firefox6-06-jemalloc.diff: * patches/firefox6-09-ipc.diff: * patches/firefox6-10-appname-tr.diff: * patches/firefox6-12-xpcom-glue-no-hidden.diff: * patches/firefox6-13-gen-devel-files.diff: * patches/firefox6-14-getting-started.diff: * patches/firefox6-19-xpcom-sparc-compile.diff: * patches/firefox6-24-storage-test.diff: * patches/firefox6-26-pgo-ss12_2.diff: * patches/firefox6-27-methoidjit-sparc.diff: * patches/firefox6-28-patch-for-debugging.diff: * patches/firefox6-32-yasm.diff: * patches/firefox6-33-wifi.diff: * patches/firefox6-34-xbgr-plugin.diff: * patches/firefox6-36-gtkembed.diff: * patches/firefox6-37-glxtest.diff: * patches/firefox6-38-copy-paste-key.diff: * patches/yelp-03-using-firefox4-gecko.diff: * specs/SUNWfirefox.spec:
ChangeLog
base-specs/firefox.spec
ext-sources/firefox-js.pc.in
ext-sources/firefox-plugin.pc.in
ext-sources/firefox-xpcom.pc.in
ext-sources/firefox60-profile-sparc-ss12-2.tar.bz2
ext-sources/firefox60-profile-x86-ss12-2.tar.bz2
patches/devhelp-02-gecko20.diff
patches/firefox6-06-jemalloc.diff
patches/firefox6-09-ipc.diff
patches/firefox6-10-appname-tr.diff
patches/firefox6-12-xpcom-glue-no-hidden.diff
patches/firefox6-13-gen-devel-files.diff
patches/firefox6-14-getting-started.diff
patches/firefox6-19-xpcom-sparc-compile.diff
patches/firefox6-24-storage-test.diff
patches/firefox6-26-pgo-ss12_2.diff
patches/firefox6-27-methoidjit-sparc.diff
patches/firefox6-28-patch-for-debugging.diff
patches/firefox6-32-yasm.diff
patches/firefox6-33-wifi.diff
patches/firefox6-34-xbgr-plugin.diff
patches/firefox6-36-gtkembed.diff
patches/firefox6-37-glxtest.diff
patches/firefox6-38-copy-paste-key.diff
patches/yelp-03-using-firefox4-gecko.diff
specs/SUNWfirefox.spec
--- a/ChangeLog	Mon Aug 15 01:46:22 2011 +0000
+++ b/ChangeLog	Mon Aug 15 02:22:00 2011 +0000
@@ -1,3 +1,32 @@
+2011-08-15  Ginn Chen  <[email protected]>
+
+	* base-specs/firefox.spec: Update Firefox to 6.0.
+	* ext-sources/firefox-js.pc.in:
+	* ext-sources/firefox-plugin.pc.in:
+	* ext-sources/firefox-xpcom.pc.in:
+	* ext-sources/firefox60-profile-sparc-ss12-2.tar.bz2:
+	* ext-sources/firefox60-profile-x86-ss12-2.tar.bz2:
+	* patches/devhelp-02-gecko20.diff:
+	* patches/firefox6-06-jemalloc.diff:
+	* patches/firefox6-09-ipc.diff:
+	* patches/firefox6-10-appname-tr.diff:
+	* patches/firefox6-12-xpcom-glue-no-hidden.diff:
+	* patches/firefox6-13-gen-devel-files.diff:
+	* patches/firefox6-14-getting-started.diff:
+	* patches/firefox6-19-xpcom-sparc-compile.diff:
+	* patches/firefox6-24-storage-test.diff:
+	* patches/firefox6-26-pgo-ss12_2.diff:
+	* patches/firefox6-27-methoidjit-sparc.diff:
+	* patches/firefox6-28-patch-for-debugging.diff:
+	* patches/firefox6-32-yasm.diff:
+	* patches/firefox6-33-wifi.diff:
+	* patches/firefox6-34-xbgr-plugin.diff:
+	* patches/firefox6-36-gtkembed.diff:
+	* patches/firefox6-37-glxtest.diff:
+	* patches/firefox6-38-copy-paste-key.diff:
+	* patches/yelp-03-using-firefox4-gecko.diff:
+	* specs/SUNWfirefox.spec:
+
 2011-08-15  Lin Ma  <[email protected]>
 
 	* specs/SUNWthunderbird.spec: Missing Buildreqire SUNWxorg-mesa
--- a/base-specs/firefox.spec	Mon Aug 15 01:46:22 2011 +0000
+++ b/base-specs/firefox.spec	Mon Aug 15 02:22:00 2011 +0000
@@ -13,8 +13,8 @@
 
 Name:        firefox
 Summary:     Mozilla Firefox Web browser
-Version:     5.0
-%define tarball_version 5.0
+Version:     6.0
+%define tarball_version 6.0
 Release:     1
 Copyright:   MPL
 License:     MPL
@@ -38,9 +38,9 @@
 %define studio_12_2 %($CC -V 2>&1 | grep -c 5\.11)
 
 %ifarch sparc
-Source8:     firefox50-profile-sparc-ss12-2.tar.bz2
+Source8:     firefox60-profile-sparc-ss12-2.tar.bz2
 %else
-Source8:     firefox50-profile-x86-ss12-2.tar.bz2
+Source8:     firefox60-profile-x86-ss12-2.tar.bz2
 %endif
 
 %if %option_with_indiana_branding
@@ -69,7 +69,7 @@
 
 # owner:ginnchen date:2008-10-15 type:feature
 # bugzilla:457196
-Patch6: firefox-06-jemalloc.diff
+Patch6: firefox6-06-jemalloc.diff
 
 # owner:ginnchen date:2011-03-07 type:bug
 Patch7: firefox-07-uconv_sse2.diff
@@ -80,24 +80,23 @@
 %endif
 
 # owner:ginnchen date:2011-03-07 type:feature
-Patch9: firefox-09-ipc.diff
+Patch9: firefox6-09-ipc.diff
 
-# owner:ginnchen date:2011-06-20 type:bug
-# bugzilla:654655 status:upstream
-Patch10: firefox-10-mathutil-compile.diff
+# owner:ginnchen date:2011-07-18 type:bug
+Patch10: firefox6-10-appname-tr.diff
 
 # owner:ginnchen date:2011-04-18 type:feature
 Patch11: firefox-11-sqlite-unix-excl.diff
 
 # owner:hawklu date:2008-12-16 type:branding
-Patch12: firefox-12-xpcom-glue-no-hidden.diff
+Patch12: firefox6-12-xpcom-glue-no-hidden.diff
 
 # owner:hawklu date:2008-04-20 type:branding
-Patch13: firefox-13-gen-devel-files.diff
+Patch13: firefox6-13-gen-devel-files.diff
 
 %if %option_with_indiana_branding
 # owner:davelam date:2009-03-02 type:branding
-Patch14: firefox-14-getting-started.diff
+Patch14: firefox6-14-getting-started.diff
 %endif
 
 # owner:hawklu date:2009-05-22 type:branding
@@ -113,7 +112,7 @@
 Patch18: firefox-18-libvpx-compile.diff
 
 # owner:ginnchen date:2011-03-08 type:feature
-Patch19: firefox-19-xpcom-sparc-compile.diff
+Patch19: firefox6-19-xpcom-sparc-compile.diff
 
 # owner:ginnchen date:2010-12-10 type:feature
 Patch20: firefox-20-ots-makepair.diff
@@ -131,20 +130,20 @@
 %if %option_without_moz_nss_nspr
 # owner:ginnchen date:2010-03-04 type:branding
 # we need to move -lsqlite3 ahead of -L/usr/lib/mps
-Patch24: firefox-24-storage-test.diff
+Patch24: firefox6-24-storage-test.diff
 %endif
 
 # owner:ginnchen date:2011-06-20 type:feature
 Patch25: firefox-25-json-compile.diff
 
 # owner:ginnchen date:2010-03-14 type:feature
-Patch26: firefox-26-pgo-ss12_2.diff
+Patch26: firefox6-26-pgo-ss12_2.diff
 
 # owner:ginnchen date:2011-04-06 type:feature bugzilla:610323
-Patch27: firefox-27-methoidjit-sparc.diff
+Patch27: firefox6-27-methoidjit-sparc.diff
 
 # owner:ginnchen date:2010-03-14 type:feature
-Patch28: firefox-28-patch-for-debugging.diff
+Patch28: firefox6-28-patch-for-debugging.diff
 
 # owner:ginnchen date:2010-03-14 type:bug bugzilla:572983
 Patch29: firefox-29-sparc-ctypes-int-overflow.diff
@@ -156,25 +155,25 @@
 Patch31: firefox-31-async-channel-crash.diff
 
 # owner:ginnchen date:2010-06-20 type:branding
-Patch32: firefox-32-yasm.diff
+Patch32: firefox6-32-yasm.diff
 
-# owner:ginnchen date:2010-05-23 type:bug bugzilla:657296 status:upstream
-Patch33: firefox-33-a11y-crash.diff
+# owner:ginnchen date:2010-07-18 type:bug bugzilla:673862 status:upstream
+Patch33: firefox6-33-wifi.diff
 
 # owner:ginnchen date:2010-06-01 type:bug bugzilla:657874 status:upstream
-Patch34: firefox-34-xbgr-plugin.diff
+Patch34: firefox6-34-xbgr-plugin.diff
 
 # owner:ginnchen date:2010-06-20 type:branding
 Patch35: firefox-35-static-assert.diff
 
 # owner:ginnchen date:2010-06-20 type:branding
-Patch36: firefox-36-gtkembed.diff
+Patch36: firefox6-36-gtkembed.diff
 
-# owner:ginnchen date:2010-07-04 type:bug bugzilla:648741 status:upstream
-Patch37: firefox-37-x11-glx.diff
+# owner:ginnchen date:2010-07-18 type:bug bugzilla:674468 status:upstream
+Patch37: firefox6-37-glxtest.diff
 
 # owner:ginnchen date:2010-07-04 type:bug bugzilla:665406 status:upstream
-Patch38: firefox-38-copy-paste-key.diff
+Patch38: firefox6-38-copy-paste-key.diff
 
 # owner:ginnchen date:2010-07-04 type:branding
 # for snv_168 or later
@@ -321,7 +320,7 @@
 export MOZCONFIG=$PWD/.mozconfig
 
 %if %option_with_indiana_branding
-cp %{SOURCE9} ${SRCDIR}/mozilla-release/other-licenses/branding/firefox/content
+cp %{SOURCE9} ${SRCDIR}/mozilla-release/browser/branding/official/content
 %endif
 
 mkdir -p ../obj
@@ -393,8 +392,6 @@
 cd firefox*
 find . | xargs touch
 mv sdk/bin/xpidl  ${LIBDIR}
-mv sdk/bin/xpt_link  ${LIBDIR}
-mv sdk/bin/xpt_dump  ${LIBDIR}
 
 mv include/* ${INCLUDEDIR}
 mv idl/* ${IDLDIR}
@@ -476,6 +473,8 @@
 /bin/rm -rf $RPM_BUILD_ROOT
 
 %changelog
+* Fri Aug 12 2011 - [email protected]
+- Bump to Firefox 6.0.
 * Tue Jul 12 2011 - [email protected]
 - Bump to Firefox 5.0.
 * Fri Apr 29 2011 - [email protected]
--- a/ext-sources/firefox-js.pc.in	Mon Aug 15 01:46:22 2011 +0000
+++ b/ext-sources/firefox-js.pc.in	Mon Aug 15 02:22:00 2011 +0000
@@ -5,7 +5,7 @@
 
 Name: JavaScript
 Description: The Mozilla JavaScript Library
-Version: 5.0
+Version: 6.0
 REQUIRES_NSPR
 Libs: -L${libdir} -R${libdir} NSPR_RUNPATH -lxul NSPR_LIB
 Cflags: -I${includedir} NSPR_INCLUDE -DXP_UNIX -DJS_THREADSAFE
--- a/ext-sources/firefox-plugin.pc.in	Mon Aug 15 01:46:22 2011 +0000
+++ b/ext-sources/firefox-plugin.pc.in	Mon Aug 15 02:22:00 2011 +0000
@@ -5,6 +5,6 @@
 
 Name: Mozilla Plug-In API
 Description: Mozilla Plug-In API
-Version: 5.0
-Requires: firefox-xpcom = 5.0
+Version: 6.0
+Requires: firefox-xpcom = 6.0
 Cflags: -DXP_UNIX -I${includedir}
--- a/ext-sources/firefox-xpcom.pc.in	Mon Aug 15 01:46:22 2011 +0000
+++ b/ext-sources/firefox-xpcom.pc.in	Mon Aug 15 02:22:00 2011 +0000
@@ -6,7 +6,7 @@
 
 Name: XPCOM
 Description: The Mozilla Cross Platform Component Library
-Version: 5.0
+Version: 6.0
 REQUIRES_NSPR
 Libs: -L${libdir} -R${libdir} NSPR_RUNPATH -lxpcom -lxul -lmozalloc NSPR_LIB
 Cflags:-I${includedir} NSPR_INCLUDE -D_XOPEN_SOURCE=500 -D__EXTENSIONS__ -DMOZ_DEFAULT_TOOLKIT=\"cairo-gtk2\" -features=no%except
Binary file ext-sources/firefox60-profile-sparc-ss12-2.tar.bz2 has changed
Binary file ext-sources/firefox60-profile-x86-ss12-2.tar.bz2 has changed
--- a/patches/devhelp-02-gecko20.diff	Mon Aug 15 01:46:22 2011 +0000
+++ b/patches/devhelp-02-gecko20.diff	Mon Aug 15 02:22:00 2011 +0000
@@ -14,7 +14,7 @@
  version = "1.8.1";
  #else
 -if (strncmp (MOZILLA_VERSION, "1.9", strlen ("1.9")) == 0) {
-+if ((strncmp (MOZILLA_VERSION, "2.0", strlen ("2.0")) == 0) || (strncmp (MOZILLA_VERSION, "5.0", strlen ("5.0")) == 0)) {
++if ((strncmp (MOZILLA_VERSION, "2.0", strlen ("2.0")) == 0) || (strncmp (MOZILLA_VERSION, "5.0", strlen ("5.0")) == 0) || (strncmp (MOZILLA_VERSION, "6.0", strlen ("6.0")) == 0)) {
 +	version = "2.0";
 +} else if (strncmp (MOZILLA_VERSION, "1.9", strlen ("1.9")) == 0) {
  	version = "1.9";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/firefox6-06-jemalloc.diff	Mon Aug 15 02:22:00 2011 +0000
@@ -0,0 +1,98 @@
+diff --git a/config/jemalloc_solaris.map b/config/jemalloc_solaris.map
+new file mode 100644
+index 0000000..7f4db39
+--- /dev/null
++++ b/config/jemalloc_solaris.map
+@@ -0,0 +1,12 @@
++{
++    global:
++        calloc             = NODIRECT;
++        free               = NODIRECT;
++        jemalloc_stats     = NODIRECT;
++        malloc             = NODIRECT;
++        malloc_usable_size = NODIRECT;
++        memalign           = NODIRECT;
++        posix_memalign     = NODIRECT;
++        realloc            = NODIRECT;
++        valloc             = NODIRECT;
++};
+diff --git a/js/src/config/jemalloc_solaris.map b/js/src/config/jemalloc_solaris.map
+new file mode 100644
+index 0000000..7f4db39
+--- /dev/null
++++ b/js/src/config/jemalloc_solaris.map
+@@ -0,0 +1,12 @@
++{
++    global:
++        calloc             = NODIRECT;
++        free               = NODIRECT;
++        jemalloc_stats     = NODIRECT;
++        malloc             = NODIRECT;
++        malloc_usable_size = NODIRECT;
++        memalign           = NODIRECT;
++        posix_memalign     = NODIRECT;
++        realloc            = NODIRECT;
++        valloc             = NODIRECT;
++};
+diff --git a/config/config.mk b/config/config.mk
+index 8aef9e5..1ddeaad 100644
+--- a/config/config.mk
++++ b/config/config.mk
+@@ -147,7 +147,7 @@
+ MOZ_WIDGET_SUPPORT_LIBS    = $(DIST)/lib/$(LIB_PREFIX)widgetsupport_s.$(LIB_SUFFIX)
+ 
+ ifdef MOZ_MEMORY
+-ifneq ($(OS_ARCH),WINNT)
++ifneq (,$(filter-out WINNT SunOS,$(OS_ARCH)))
+ JEMALLOC_LIBS = $(MKSHLIB_FORCE_ALL) $(call EXPAND_MOZLIBNAME,jemalloc) $(MKSHLIB_UNFORCE_ALL)
+ # If we are linking jemalloc into a program, we want the jemalloc symbols
+ # to be exported
+diff --git a/js/src/config/config.mk b/js/src/config/config.mk
+index 8aef9e5..1ddeaad 100644
+--- a/js/src/config/config.mk
++++ b/js/src/config/config.mk
+@@ -147,7 +147,7 @@
+ MOZ_WIDGET_SUPPORT_LIBS    = $(DIST)/lib/$(LIB_PREFIX)widgetsupport_s.$(LIB_SUFFIX)
+ 
+ ifdef MOZ_MEMORY
+-ifneq ($(OS_ARCH),WINNT)
++ifneq (,$(filter-out WINNT SunOS,$(OS_ARCH)))
+ JEMALLOC_LIBS = $(MKSHLIB_FORCE_ALL) $(call EXPAND_MOZLIBNAME,jemalloc) $(MKSHLIB_UNFORCE_ALL)
+ # If we are linking jemalloc into a program, we want the jemalloc symbols
+ # to be exported
+diff --git a/toolkit/library/Makefile.in b/toolkit/library/Makefile.in
+index 841a77b..bf10981 100644
+--- a/toolkit/library/Makefile.in
++++ b/toolkit/library/Makefile.in
+@@ -246,6 +246,12 @@
+ 
+ include $(srcdir)/libxul-rules.mk
+ 
++ifdef MOZ_MEMORY
++ifeq ($(OS_ARCH),SunOS)
++EXTRA_DSO_LDOPTS += $(call EXPAND_LIBNAME_PATH,jemalloc,$(DIST)/lib) -M $(topsrcdir)/config/jemalloc_solaris.map -z interpose
++endif
++endif
++
+ ifeq ($(OS_ARCH),OpenBSD)
+ # Needed by nsAuthGSSAPI
+ EXTRA_DSO_LDOPTS += -lkrb5 -lcrypto
+diff --git a/xpcom/build/Makefile.in b/xpcom/build/Makefile.in
+index 9421f4c..52a110b 100644
+--- a/xpcom/build/Makefile.in
++++ b/xpcom/build/Makefile.in
+@@ -191,6 +191,14 @@ ifdef HAVE_CLOCK_MONOTONIC
+ EXTRA_DSO_LDOPTS += $(REALTIME_LIBS)
+ endif
+ 
++ifndef MOZ_ENABLE_LIBXUL
++ifdef MOZ_MEMORY
++ifeq ($(OS_ARCH),SunOS)
++EXTRA_DSO_LDOPTS += $(call EXPAND_LIBNAME_PATH,jemalloc,$(DIST)/lib) -M $(topsrcdir)/config/jemalloc_solaris.map -z interpose
++endif
++endif
++endif
++
+ ifeq ($(OS_ARCH),WINNT)
+ OS_LIBS += $(call EXPAND_LIBNAME,shell32 ole32 uuid version)
+ ifneq (,$(MOZ_DEBUG)$(NS_TRACE_MALLOC))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/firefox6-09-ipc.diff	Mon Aug 15 02:22:00 2011 +0000
@@ -0,0 +1,4580 @@
+diff --git a/dom/plugins/ipc/PluginMessageUtils.cpp b/dom/plugins/ipc/PluginMessageUtils.cpp
+index bd04aa9..6a3e7d3 100644
+--- a/dom/plugins/ipc/PluginMessageUtils.cpp
++++ b/dom/plugins/ipc/PluginMessageUtils.cpp
+@@ -115,7 +115,7 @@
+ string
+ MungePluginDsoPath(const string& path)
+ {
+-#if defined(OS_LINUX)
++#if defined(OS_LINUX) || defined(OS_SOLARIS)
+   // https://bugzilla.mozilla.org/show_bug.cgi?id=519601
+   return ReplaceAll(path, "netscape", "netsc@pe");
+ #else
+@@ -126,7 +126,7 @@
+ string
+ UnmungePluginDsoPath(const string& munged)
+ {
+-#if defined(OS_LINUX)
++#if defined(OS_LINUX) || defined(OS_SOLARIS)
+   return ReplaceAll(munged, "netsc@pe", "netscape");
+ #else
+   return munged;
+diff --git a/dom/plugins/ipc/PluginModuleChild.cpp b/dom/plugins/ipc/PluginModuleChild.cpp
+index dec578b..ab1a998 100644
+--- a/dom/plugins/ipc/PluginModuleChild.cpp
++++ b/dom/plugins/ipc/PluginModuleChild.cpp
+@@ -212,7 +212,7 @@ PluginModuleChild::Init(const std::string& aPluginFilename,
+ 
+     // TODO: use PluginPRLibrary here
+ 
+-#if defined(OS_LINUX)
++#if defined(OS_LINUX) || defined(OS_SOLARIS)
+     mShutdownFunc =
+         (NP_PLUGINSHUTDOWN) PR_FindFunctionSymbol(mLibrary, "NP_Shutdown");
+ 
+@@ -242,9 +242,11 @@ PluginModuleChild::Init(const std::string& aPluginFilename,
+ }
+ 
+ #if defined(MOZ_WIDGET_GTK2)
++extern "C" {
+ typedef void (*GObjectDisposeFn)(GObject*);
+ typedef gboolean (*GtkWidgetScrollEventFn)(GtkWidget*, GdkEventScroll*);
+ typedef void (*GtkPlugEmbeddedFn)(GtkPlug*);
++}
+ 
+ static GObjectDisposeFn real_gtk_plug_dispose;
+ static GtkPlugEmbeddedFn real_gtk_plug_embedded;
+@@ -1714,7 +1716,7 @@ PluginModuleChild::AnswerNP_GetEntryPoints(NPError* _retval)
+     PLUGIN_LOG_DEBUG_METHOD;
+     AssertPluginThread();
+ 
+-#if defined(OS_LINUX)
++#if defined(OS_LINUX) || defined(OS_SOLARIS)
+     return true;
+ #elif defined(OS_WIN) || defined(OS_MACOSX)
+     *_retval = mGetEntryPointsFunc(&mFunctions);
+@@ -1747,7 +1749,7 @@ PluginModuleChild::AnswerNP_Initialize(NativeThreadId* tid, NPError* _retval)
+     SendBackUpXResources(FileDescriptor(xSocketFd, false/*don't close*/));
+ #endif
+ 
+-#if defined(OS_LINUX)
++#if defined(OS_LINUX) || defined(OS_SOLARIS)
+     *_retval = mInitializeFunc(&sBrowserFuncs, &mFunctions);
+     return true;
+ #elif defined(OS_WIN) || defined(OS_MACOSX)
+diff --git a/dom/plugins/ipc/PluginModuleChild.h b/dom/plugins/ipc/PluginModuleChild.h
+index ae3cc43..b1b7d8a 100644
+--- a/dom/plugins/ipc/PluginModuleChild.h
++++ b/dom/plugins/ipc/PluginModuleChild.h
+@@ -288,7 +288,7 @@ private:
+ 
+     // we get this from the plugin
+     NP_PLUGINSHUTDOWN mShutdownFunc;
+-#ifdef OS_LINUX
++#if defined(OS_LINUX) || defined(OS_SOLARIS)
+     NP_PLUGINUNIXINIT mInitializeFunc;
+ #elif defined(OS_WIN) || defined(OS_MACOSX)
+     NP_PLUGININIT mInitializeFunc;
+diff --git a/dom/plugins/ipc/PluginModuleParent.h b/dom/plugins/ipc/PluginModuleParent.h
+index e4abf55..93de1c6 100644
+--- a/dom/plugins/ipc/PluginModuleParent.h
++++ b/dom/plugins/ipc/PluginModuleParent.h
+@@ -193,7 +193,7 @@ private:
+ 
+     // Implement the module-level functions from NPAPI; these are
+     // normally resolved directly from the DSO.
+-#ifdef OS_LINUX
++#if defined(OS_LINUX) || defined(OS_SOLARIS)
+     NPError NP_Initialize(const NPNetscapeFuncs* npnIface,
+                           NPPluginFuncs* nppIface);
+ #else
+diff --git a/dom/plugins/ipc/PluginProcessParent.cpp b/dom/plugins/ipc/PluginProcessParent.cpp
+index 3d86b81..7a7d76a 100644
+--- a/dom/plugins/ipc/PluginProcessParent.cpp
++++ b/dom/plugins/ipc/PluginProcessParent.cpp
+@@ -101,6 +101,9 @@ PluginProcessParent::Launch(PRInt32 timeoutMs)
+         else if (base::PROCESS_ARCH_ARM & pluginLibArchitectures & containerArchitectures) {
+           selectedArchitecture = base::PROCESS_ARCH_ARM;
+         }
++        else if (base::PROCESS_ARCH_SPARC & pluginLibArchitectures & containerArchitectures) {
++          selectedArchitecture = base::PROCESS_ARCH_SPARC;
++        }
+         else {
+             return false;
+         }
+diff --git a/ipc/chromium/Makefile.in b/ipc/chromium/Makefile.in
+index 00b834f..1ff687a 100644
+--- a/ipc/chromium/Makefile.in
++++ b/ipc/chromium/Makefile.in
+@@ -49,7 +49,9 @@ FORCE_STATIC_LIB = 1
+ LIBXUL_LIBRARY = 1
+ EXPORT_LIBRARY = 1
+ 
++ifndef SOLARIS_SUNPRO_CC
+ ACDEFINES =
++endif
+ 
+ ifndef MOZ_NATIVE_LIBEVENT # {
+ vpath %.c \
+@@ -274,6 +276,37 @@ endif
+ 
+ endif # } OS_LINUX
+ 
++ifdef OS_SOLARIS # {
++
++CPPSRCS += \
++  atomicops_internals_x86_gcc.cc \
++  idle_timer.cc \
++  data_pack.cc \
++  file_version_info_linux.cc \
++  process_util_linux.cc \
++  base_paths_linux.cc \
++  time_posix.cc \
++  $(NULL)
++
++ifdef MOZ_ENABLE_GTK2
++CPPSRCS += \
++  message_pump_glib.cc \
++  $(NULL)
++endif
++
++ifdef MOZ_ENABLE_QT
++MOCSRCS = \
++  moc_message_pump_qt.cc \
++  $(NULL)
++
++CPPSRCS += \
++  $(MOCSRCS) \
++  message_pump_qt.cc \
++  $(NULL)
++endif
++
++endif # } OS_SOLARIS
++
+ # libevent
+ 
+ ifndef MOZ_NATIVE_LIBEVENT # {
+@@ -312,6 +345,14 @@ CSRCS += \
+   $(NULL)
+ endif # }
+ 
++ifdef OS_SOLARIS # {
++LOCAL_INCLUDES += -I$(srcdir)/src/third_party/libevent/solaris
++CSRCS += \
++  devpoll.c \
++  evport.c \
++  $(NULL)
++endif # }
++
+ endif # }
+ 
+ endif # }
+diff --git a/ipc/chromium/chromium-config.mk b/ipc/chromium/chromium-config.mk
+index 8b09ed1..c243331 100644
+--- a/ipc/chromium/chromium-config.mk
++++ b/ipc/chromium/chromium-config.mk
+@@ -92,6 +92,24 @@
+ 
+ else # } {
+ 
++ifeq ($(OS_ARCH),SunOS) # {
++
++OS_SOLARIS = 1
++OS_POSIX = 1
++
++DEFINES += \
++  -DOS_SOLARIS=1 \
++  -DOS_POSIX=1 \
++  $(NULL)
++
++# NB: to stop gcc warnings about exporting template instantiation
++OS_CXXFLAGS := $(filter-out -pedantic,$(OS_CXXFLAGS))
++
++
++
++
++else # } {
++
+ OS_LINUX = 1
+ OS_POSIX = 1
+ 
+@@ -106,3 +124,4 @@
+ endif # }
+ endif # }
+ 
++endif # }
+diff --git a/ipc/chromium/src/base/atomicops.h b/ipc/chromium/src/base/atomicops.h
+index a31c082..eca4255 100644
+--- a/ipc/chromium/src/base/atomicops.h
++++ b/ipc/chromium/src/base/atomicops.h
+@@ -132,6 +132,10 @@ Atomic64 Release_Load(volatile const Atomic64* ptr);
+ #include "base/atomicops_internals_x86_gcc.h"
+ #elif defined(COMPILER_GCC) && defined(ARCH_CPU_ARM_FAMILY)
+ #include "base/atomicops_internals_arm_gcc.h"
++#elif defined(COMPILER_SUNPRO) && defined(ARCH_CPU_X86_FAMILY)
++#define __asm__ asm
++#define __volatile__ volatile
++#include "base/atomicops_internals_x86_gcc.h"
+ #else
+ #include "base/atomicops_internals_mutex.h"
+ #endif
+diff --git a/ipc/chromium/src/base/atomicops_internals_x86_gcc.cc b/ipc/chromium/src/base/atomicops_internals_x86_gcc.cc
+index 933ca51..b0b3eb1 100644
+--- a/ipc/chromium/src/base/atomicops_internals_x86_gcc.cc
++++ b/ipc/chromium/src/base/atomicops_internals_x86_gcc.cc
+@@ -19,13 +19,13 @@
+ // Inline cpuid instruction.  In PIC compilations, %ebx contains the address
+ // of the global offset table.  To avoid breaking such executables, this code
+ // must preserve that register's value across cpuid instructions.
+-#if defined(__i386__)
++#if defined(__i386__) || defined (__i386)
+ #define cpuid(a, b, c, d, inp) \
+   asm ("mov %%ebx, %%edi\n"    \
+        "cpuid\n"               \
+        "xchg %%edi, %%ebx\n"   \
+        : "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp))
+-#elif defined (__x86_64__)
++#elif defined (__x86_64__) || defined(__x86_64)
+ #define cpuid(a, b, c, d, inp) \
+   asm ("mov %%rbx, %%rdi\n"    \
+        "cpuid\n"               \
+diff --git a/ipc/chromium/src/base/atomicops_internals_x86_gcc.h b/ipc/chromium/src/base/atomicops_internals_x86_gcc.h
+index fda5029..364beee 100644
+--- a/ipc/chromium/src/base/atomicops_internals_x86_gcc.h
++++ b/ipc/chromium/src/base/atomicops_internals_x86_gcc.h
+@@ -29,18 +29,18 @@ inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+                                          Atomic32 old_value,
+                                          Atomic32 new_value) {
+   Atomic32 prev;
+-  __asm__ __volatile__("lock; cmpxchgl %1,%2"
++  __asm__ __volatile__("lock; cmpxchgl %1,(%2)"
+                        : "=a" (prev)
+-                       : "q" (new_value), "m" (*ptr), "0" (old_value)
++                       : "q" (new_value), "r" (ptr), "0" (old_value)
+                        : "memory");
+   return prev;
+ }
+ 
+ inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
+                                          Atomic32 new_value) {
+-  __asm__ __volatile__("xchgl %1,%0"  // The lock prefix is implicit for xchg.
++  __asm__ __volatile__("xchgl (%1),%0"  // The lock prefix is implicit for xchg.
+                        : "=r" (new_value)
+-                       : "m" (*ptr), "0" (new_value)
++                       : "r" (ptr), "0" (new_value)
+                        : "memory");
+   return new_value;  // Now it's the previous value.
+ }
+@@ -48,8 +48,8 @@ inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
+ inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
+                                           Atomic32 increment) {
+   Atomic32 temp = increment;
+-  __asm__ __volatile__("lock; xaddl %0,%1"
+-                       : "+r" (temp), "+m" (*ptr)
++  __asm__ __volatile__("lock; xaddl %0,(%1)"
++                       : "+r" (temp), "+r" (ptr)
+                        : : "memory");
+   // temp now holds the old value of *ptr
+   return temp + increment;
+@@ -58,8 +58,8 @@ inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
+ inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
+                                         Atomic32 increment) {
+   Atomic32 temp = increment;
+-  __asm__ __volatile__("lock; xaddl %0,%1"
+-                       : "+r" (temp), "+m" (*ptr)
++  __asm__ __volatile__("lock; xaddl %0,(%1)"
++                       : "+r" (temp), "+r" (ptr)
+                        : : "memory");
+   // temp now holds the old value of *ptr
+   if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
+@@ -153,18 +153,18 @@ inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
+                                          Atomic64 old_value,
+                                          Atomic64 new_value) {
+   Atomic64 prev;
+-  __asm__ __volatile__("lock; cmpxchgq %1,%2"
++  __asm__ __volatile__("lock; cmpxchgq %1,(%2)"
+                        : "=a" (prev)
+-                       : "q" (new_value), "m" (*ptr), "0" (old_value)
++                       : "q" (new_value), "r" (ptr), "0" (old_value)
+                        : "memory");
+   return prev;
+ }
+ 
+ inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
+                                          Atomic64 new_value) {
+-  __asm__ __volatile__("xchgq %1,%0"  // The lock prefix is implicit for xchg.
++  __asm__ __volatile__("xchgq (%1),%0"  // The lock prefix is implicit for xchg.
+                        : "=r" (new_value)
+-                       : "m" (*ptr), "0" (new_value)
++                       : "r" (ptr), "0" (new_value)
+                        : "memory");
+   return new_value;  // Now it's the previous value.
+ }
+@@ -172,8 +172,8 @@ inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
+ inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
+                                           Atomic64 increment) {
+   Atomic64 temp = increment;
+-  __asm__ __volatile__("lock; xaddq %0,%1"
+-                       : "+r" (temp), "+m" (*ptr)
++  __asm__ __volatile__("lock; xaddq %0,(%1)"
++                       : "+r" (temp), "+r" (ptr)
+                        : : "memory");
+   // temp now contains the previous value of *ptr
+   return temp + increment;
+@@ -182,8 +182,8 @@ inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
+ inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
+                                         Atomic64 increment) {
+   Atomic64 temp = increment;
+-  __asm__ __volatile__("lock; xaddq %0,%1"
+-                       : "+r" (temp), "+m" (*ptr)
++  __asm__ __volatile__("lock; xaddq %0,(%1)"
++                       : "+r" (temp), "+r" (ptr)
+                        : : "memory");
+   // temp now contains the previous value of *ptr
+   if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
+diff --git a/ipc/chromium/src/base/base_paths.h b/ipc/chromium/src/base/base_paths.h
+index 5f08dc4..a85534e 100644
+--- a/ipc/chromium/src/base/base_paths.h
++++ b/ipc/chromium/src/base/base_paths.h
+@@ -13,7 +13,7 @@
+ #include "base/base_paths_win.h"
+ #elif defined(OS_MACOSX)
+ #include "base/base_paths_mac.h"
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+ #include "base/base_paths_linux.h"
+ #endif
+ #include "base/path_service.h"
+diff --git a/ipc/chromium/src/base/base_paths_linux.cc b/ipc/chromium/src/base/base_paths_linux.cc
+index b235f6b..865c348 100644
+--- a/ipc/chromium/src/base/base_paths_linux.cc
++++ b/ipc/chromium/src/base/base_paths_linux.cc
+@@ -21,11 +21,19 @@ bool PathProviderLinux(int key, FilePath* result) {
+     case base::FILE_EXE:
+     case base::FILE_MODULE: { // TODO(evanm): is this correct?
+       char bin_dir[PATH_MAX + 1];
++#ifdef OS_SOLARIS
++      if (!(realpath(getexecname(), bin_dir) && bin_dir[0] != '[')) {
++        NOTREACHED() << "Unable to get exec name.";
++        return false;
++      }
++      int bin_dir_size = strlen(bin_dir);
++#else
+       int bin_dir_size = readlink("/proc/self/exe", bin_dir, PATH_MAX);
+       if (bin_dir_size < 0 || bin_dir_size > PATH_MAX) {
+         NOTREACHED() << "Unable to resolve /proc/self/exe.";
+         return false;
+       }
++#endif      
+       bin_dir[bin_dir_size] = 0;
+       *result = FilePath(bin_dir);
+       return true;
+diff --git a/ipc/chromium/src/base/basictypes.h b/ipc/chromium/src/base/basictypes.h
+index dd2595c..ea2ba0c 100644
+--- a/ipc/chromium/src/base/basictypes.h
++++ b/ipc/chromium/src/base/basictypes.h
+@@ -109,9 +109,15 @@ const  int64 kint64max  = (( int64) GG_LONGLONG(0x7FFFFFFFFFFFFFFF));
+ #  if defined(OS_POSIX)
+ #    define __STDC_FORMAT_MACROS 1
+ #    include <inttypes.h>           // for 64-bit integer format macros
++#   if defined(COMPILER_SUNPRO)
++#    define PRId64L L"I64d"
++#    define PRIu64L L"I64u"
++#    define PRIx64L L"I64x"
++#   else
+ #    define PRId64L "I64d"
+ #    define PRIu64L "I64u"
+ #    define PRIx64L "I64x"
++#   endif
+ #  elif defined(OS_WIN)
+ #    define PRId64 "I64d"
+ #    define PRIu64 "I64u"
+@@ -155,6 +161,7 @@ const  int64 kint64max  = (( int64) GG_LONGLONG(0x7FFFFFFFFFFFFFFF));
+ // This template function declaration is used in defining arraysize.
+ // Note that the function doesn't need an implementation, as we only
+ // use its type.
++#if !defined(COMPILER_SUNPRO) || __SUNPRO_CC >= 0x5100
+ template <typename T, size_t N>
+ char (&ArraySizeHelper(T (&array)[N]))[N];
+ 
+@@ -167,6 +174,7 @@ char (&ArraySizeHelper(const T (&array)[N]))[N];
+ #endif
+ 
+ #define arraysize(array) (sizeof(ArraySizeHelper(array)))
++#endif
+ 
+ // ARRAYSIZE_UNSAFE performs essentially the same calculation as arraysize,
+ // but can be used on anonymous types or types defined inside
+@@ -209,6 +217,9 @@ char (&ArraySizeHelper(const T (&array)[N]))[N];
+   ((sizeof(a) / sizeof(*(a))) / \
+    static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
+ 
++#if defined(COMPILER_SUNPRO) && __SUNPRO_CC < 0x5100
++#define arraysize(array) (ARRAYSIZE_UNSAFE(array))
++#endif
+ 
+ // Use implicit_cast as a safe version of static_cast or const_cast
+ // for upcasting in the type hierarchy (i.e. casting a pointer to Foo
+diff --git a/ipc/chromium/src/base/clipboard.cc b/ipc/chromium/src/base/clipboard.cc
+index e41fd93..fc6b7f2 100644
+--- a/ipc/chromium/src/base/clipboard.cc
++++ b/ipc/chromium/src/base/clipboard.cc
+@@ -50,13 +50,13 @@ void Clipboard::DispatchObject(ObjectType type, const ObjectMapParams& params) {
+       WriteWebSmartPaste();
+       break;
+ 
+-#if defined(OS_WIN) || defined(OS_LINUX)
++#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_SOLARIS)
+     case CBF_BITMAP:
+       if (!IsBitmapSafe(params))
+         return;
+       WriteBitmap(&(params[0].front()), &(params[1].front()));
+       break;
+-#endif  // defined(OS_WIN) || defined(OS_LINUX)
++#endif  // defined(OS_WIN) || defined(OS_LINUX) || defined(OS_SOLARIS)
+ 
+     default:
+       NOTREACHED();
+diff --git a/ipc/chromium/src/base/clipboard.h b/ipc/chromium/src/base/clipboard.h
+index 98f3b31..c18e5d2 100644
+--- a/ipc/chromium/src/base/clipboard.h
++++ b/ipc/chromium/src/base/clipboard.h
+@@ -17,7 +17,7 @@
+ class Clipboard {
+  public:
+   typedef std::string FormatType;
+-#if defined(OS_LINUX)
++#if defined(OS_LINUX) || defined(OS_SOLARIS)
+   typedef struct _GtkClipboard GtkClipboard;
+   typedef std::map<FormatType, std::pair<char*, size_t> > TargetMap;
+ #endif
+@@ -179,7 +179,7 @@ class Clipboard {
+ 
+   // True if we can create a window.
+   bool create_window_;
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+   // Data is stored in the |clipboard_data_| map until it is saved to the system
+   // clipboard. The Store* functions save data to the |clipboard_data_| map. The
+   // SetGtkClipboard function replaces whatever is on the system clipboard with
+diff --git a/ipc/chromium/src/base/crypto/signature_verifier.h b/ipc/chromium/src/base/crypto/signature_verifier.h
+index 18873e8..3dd9aac 100644
+--- a/ipc/chromium/src/base/crypto/signature_verifier.h
++++ b/ipc/chromium/src/base/crypto/signature_verifier.h
+@@ -7,7 +7,7 @@
+ 
+ #include "build/build_config.h"
+ 
+-#if defined(OS_LINUX)
++#if defined(OS_LINUX) || defined(OS_SOLARIS)
+ #include <cryptoht.h>
+ #elif defined(OS_MACOSX)
+ #include <Security/cssm.h>
+@@ -81,7 +81,7 @@ class SignatureVerifier {
+ 
+   std::vector<uint8> signature_;
+ 
+-#if defined(OS_LINUX)
++#if defined(OS_LINUX) || defined(OS_SOLARIS)
+   VFYContext* vfy_context_;
+ #elif defined(OS_MACOSX)
+   std::vector<uint8> public_key_info_;
+diff --git a/ipc/chromium/src/base/debug_util_posix.cc b/ipc/chromium/src/base/debug_util_posix.cc
+index ed9ad4f..fed5c45 100644
+--- a/ipc/chromium/src/base/debug_util_posix.cc
++++ b/ipc/chromium/src/base/debug_util_posix.cc
+@@ -13,8 +13,10 @@
+ #include <unistd.h>
+ #ifndef ANDROID
+ #include <execinfo.h>
++#ifndef OS_SOLARIS
+ #include <sys/sysctl.h>
+ #endif
++#endif
+ 
+ #include "base/basictypes.h"
+ #include "base/eintr_wrapper.h"
+@@ -71,7 +73,7 @@ bool DebugUtil::BeingDebugged() {
+   return being_debugged;
+ }
+ 
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+ 
+ // We can look in /proc/self/status for TracerPid.  We are likely used in crash
+ // handling, so we are careful not to use the heap or have side effects.
+@@ -106,13 +108,17 @@ bool DebugUtil::BeingDebugged() {
+   return pid_index < status.size() && status[pid_index] != '0';
+ }
+ 
+-#endif  // OS_LINUX
++#endif  // OS_LINUX || OS_SOLARIS
+ 
+ // static
+ void DebugUtil::BreakDebugger() {
+ #if defined(ARCH_CPU_X86_FAMILY)
++#if defined(COMPILER_SUNPRO)
++  asm ("int $3");
++#else
+   asm ("int3");
+ #endif
++#endif
+ }
+ 
+ StackTrace::StackTrace() {
+diff --git a/ipc/chromium/src/base/eintr_wrapper.h b/ipc/chromium/src/base/eintr_wrapper.h
+index a3fb1e4..fa44e05 100644
+--- a/ipc/chromium/src/base/eintr_wrapper.h
++++ b/ipc/chromium/src/base/eintr_wrapper.h
+@@ -16,6 +16,7 @@
+ 
+ #include <errno.h>
+ 
++#ifndef COMPILER_SUNPRO
+ #define HANDLE_EINTR(x) ({ \
+   typeof(x) __eintr_result__; \
+   do { \
+@@ -23,6 +24,15 @@
+   } while (__eintr_result__ == -1 && errno == EINTR); \
+   __eintr_result__;\
+ })
++#else
++#define HANDLE_EINTR(x) ({ \
++  ssize_t __eintr_result__; \
++  do { \
++    __eintr_result__ = x; \
++  } while (__eintr_result__ == -1 && errno == EINTR); \
++  __eintr_result__;\
++})
++#endif
+ 
+ #else
+ 
+diff --git a/ipc/chromium/src/base/file_util.cc b/ipc/chromium/src/base/file_util.cc
+index b79a7b6..cc98243 100644
+--- a/ipc/chromium/src/base/file_util.cc
++++ b/ipc/chromium/src/base/file_util.cc
+@@ -16,10 +16,8 @@
+ 
+ #include "base/file_path.h"
+ #include "base/logging.h"
+-#include "base/string_util.h"
+-
+ #include "base/string_piece.h"
+-#include "base/sys_string_conversions.h"
++#include "base/string_util.h"
+ 
+ namespace {
+ 
+@@ -29,34 +27,6 @@ const FilePath::CharType kExtensionSeparator = FILE_PATH_LITERAL('.');
+ 
+ namespace file_util {
+ 
+-void PathComponents(const FilePath& path,
+-                    std::vector<FilePath::StringType>* components) {
+-  DCHECK(components);
+-  if (!components)
+-    return;
+-
+-  FilePath::StringType path_str = path.value();
+-  FilePath::StringType::size_type start = 0;
+-  FilePath::StringType::size_type end =
+-      path_str.find_first_of(FilePath::kSeparators);
+-
+-  // If the path starts with a separator, add it to components.
+-  if (end == start) {
+-    components->push_back(FilePath::StringType(path_str, 0, 1));
+-    start = end + 1;
+-    end = path_str.find_first_of(FilePath::kSeparators, start);
+-  }
+-  while (end != FilePath::StringType::npos) {
+-    FilePath::StringType component =
+-        FilePath::StringType(path_str, start, end - start);
+-    components->push_back(component);
+-    start = end + 1;
+-    end = path_str.find_first_of(FilePath::kSeparators, start);
+-  }
+-
+-  components->push_back(FilePath::StringType(path_str, start));
+-}
+-
+ bool EndsWithSeparator(const FilePath& path) {
+   FilePath::StringType value = path.value();
+   if (value.empty())
+@@ -79,11 +49,6 @@ bool EnsureEndsWithSeparator(FilePath* path) {
+   return true;
+ }
+ 
+-void TrimTrailingSeparator(std::wstring* dir) {
+-  while (dir->length() > 1 && EndsWithSeparator(dir))
+-    dir->resize(dir->length() - 1);
+-}
+-
+ FilePath::StringType GetFileExtensionFromPath(const FilePath& path) {
+   FilePath::StringType file_name = path.BaseName().value();
+   const FilePath::StringType::size_type last_dot =
+@@ -160,21 +125,60 @@ bool ContentsEqual(const FilePath& filename1, const FilePath& filename2) {
+     file1.read(buffer1, BUFFER_SIZE);
+     file2.read(buffer2, BUFFER_SIZE);
+ 
+-    if ((file1.eof() && !file2.eof()) ||
+-        (!file1.eof() && file2.eof()) ||
++    if ((file1.eof() != file2.eof()) ||
+         (file1.gcount() != file2.gcount()) ||
+         (memcmp(buffer1, buffer2, file1.gcount()))) {
+       file1.close();
+       file2.close();
+       return false;
+     }
+-  } while (!file1.eof() && !file2.eof());
++  } while (!file1.eof() || !file2.eof());
+ 
+   file1.close();
+   file2.close();
+   return true;
+ }
+ 
++bool TextContentsEqual(const FilePath& filename1, const FilePath& filename2) {
++  std::ifstream file1(filename1.value().c_str(), std::ios::in);
++  std::ifstream file2(filename2.value().c_str(), std::ios::in);
++
++  // Even if both files aren't openable (and thus, in some sense, "equal"),
++  // any unusable file yields a result of "false".
++  if (!file1.is_open() || !file2.is_open())
++    return false;
++
++  do {
++    std::string line1, line2;
++    getline(file1, line1);
++    getline(file2, line2);
++
++    // Check for mismatched EOF states, or any error state.
++    if ((file1.eof() != file2.eof()) ||
++        file1.bad() || file2.bad()) {
++      return false;
++    }
++
++    // Trim all '\r' and '\n' characters from the end of the line.
++    std::string::size_type end1 = line1.find_last_not_of("\r\n");
++    if (end1 == std::string::npos)
++      line1.clear();
++    else if (end1 + 1 < line1.length())
++      line1.erase(end1 + 1);
++
++    std::string::size_type end2 = line2.find_last_not_of("\r\n");
++    if (end2 == std::string::npos)
++      line2.clear();
++    else if (end2 + 1 < line2.length())
++      line2.erase(end2 + 1);
++
++    if (line1 != line2)
++      return false;
++  } while (!file1.eof() || !file2.eof());
++
++  return true;
++}
++
+ bool ReadFileToString(const FilePath& path, std::string* contents) {
+   FILE* file = OpenFile(path, "rb");
+   if (!file) {
+@@ -207,6 +211,14 @@ bool GetFileSize(const FilePath& file_path, int64* file_size) {
+   return true;
+ }
+ 
++bool IsDot(const FilePath& path) {
++  return FILE_PATH_LITERAL(".") == path.BaseName().value();
++}
++
++bool IsDotDot(const FilePath& path) {
++  return FILE_PATH_LITERAL("..") == path.BaseName().value();
++}
++
+ bool CloseFile(FILE* file) {
+   if (file == NULL)
+     return true;
+@@ -258,6 +270,23 @@ bool ContainsPath(const FilePath &parent, const FilePath& child) {
+   return true;
+ }
+ 
++int64 ComputeDirectorySize(const FilePath& root_path) {
++  int64 running_size = 0;
++  FileEnumerator file_iter(root_path, true, FileEnumerator::FILES);
++  for (FilePath current = file_iter.Next(); !current.empty();
++       current = file_iter.Next()) {
++    FileEnumerator::FindInfo info;
++    file_iter.GetFindInfo(&info);
++#if defined(OS_WIN)
++    LARGE_INTEGER li = { info.nFileSizeLow, info.nFileSizeHigh };
++    running_size += li.QuadPart;
++#else
++    running_size += info.stat.st_size;
++#endif
++  }
++  return running_size;
++}
++
+ ///////////////////////////////////////////////
+ // MemoryMappedFile
+ 
+@@ -265,6 +294,20 @@ MemoryMappedFile::~MemoryMappedFile() {
+   CloseHandles();
+ }
+ 
++bool MemoryMappedFile::Initialize(base::PlatformFile file) {
++  if (IsValid())
++    return false;
++
++  file_ = file;
++
++  if (!MapFileToMemoryInternal()) {
++    CloseHandles();
++    return false;
++  }
++
++  return true;
++}
++
+ bool MemoryMappedFile::Initialize(const FilePath& file_name) {
+   if (IsValid())
+     return false;
+@@ -277,6 +320,19 @@ bool MemoryMappedFile::Initialize(const FilePath& file_name) {
+   return true;
+ }
+ 
++bool MemoryMappedFile::MapFileToMemory(const FilePath& file_name) {
++  file_ = base::CreatePlatformFile(file_name.ToWStringHack(),
++      base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ,
++      NULL);
++
++  if (file_ == base::kInvalidPlatformFileValue) {
++    LOG(ERROR) << "Couldn't open " << file_name.value();
++    return false;
++  }
++
++  return MapFileToMemoryInternal();
++}
++
+ bool MemoryMappedFile::IsValid() {
+   return data_ != NULL;
+ }
+@@ -294,73 +350,33 @@ bool AbsolutePath(std::wstring* path_str) {
+   *path_str = path.ToWStringHack();
+   return true;
+ }
++
++#if defined(OS_WIN)
++// This function is deprecated; see file_util_deprecated.h for details.
+ void AppendToPath(std::wstring* path, const std::wstring& new_ending) {
+   if (!path) {
+     NOTREACHED();
+     return;  // Don't crash in this function in release builds.
+   }
+ 
+-  if (!EndsWithSeparator(path))
++  if (!EndsWithSeparator(*path))
+     path->push_back(FilePath::kSeparators[0]);
+   path->append(new_ending);
+ }
++#endif
++
+ bool CopyDirectory(const std::wstring& from_path, const std::wstring& to_path,
+                    bool recursive) {
+   return CopyDirectory(FilePath::FromWStringHack(from_path),
+                        FilePath::FromWStringHack(to_path),
+                        recursive);
+ }
+-bool ContentsEqual(const std::wstring& filename1,
+-                   const std::wstring& filename2) {
+-  return ContentsEqual(FilePath::FromWStringHack(filename1),
+-                       FilePath::FromWStringHack(filename2));
+-}
+-bool CopyFile(const std::wstring& from_path, const std::wstring& to_path) {
+-  return CopyFile(FilePath::FromWStringHack(from_path),
+-                  FilePath::FromWStringHack(to_path));
+-}
+-bool CreateDirectory(const std::wstring& full_path) {
+-  return CreateDirectory(FilePath::FromWStringHack(full_path));
+-}
+-bool CreateNewTempDirectory(const std::wstring& prefix,
+-                            std::wstring* new_temp_path) {
+-#if defined(OS_WIN)
+-  FilePath::StringType dir_prefix(prefix);
+-#elif defined(OS_POSIX)
+-  FilePath::StringType dir_prefix = WideToUTF8(prefix);
+-#endif
+-  FilePath temp_path;
+-  if (!CreateNewTempDirectory(dir_prefix, &temp_path))
+-    return false;
+-  *new_temp_path = temp_path.ToWStringHack();
+-  return true;
+-}
+-bool CreateTemporaryFileName(std::wstring* temp_file) {
+-  FilePath temp_file_path;
+-  if (!CreateTemporaryFileName(&temp_file_path))
+-    return false;
+-  *temp_file = temp_file_path.ToWStringHack();
+-  return true;
+-}
+ bool Delete(const std::wstring& path, bool recursive) {
+   return Delete(FilePath::FromWStringHack(path), recursive);
+ }
+-bool DirectoryExists(const std::wstring& path) {
+-  return DirectoryExists(FilePath::FromWStringHack(path));
+-}
+-bool EndsWithSeparator(std::wstring* path) {
+-  return EndsWithSeparator(FilePath::FromWStringHack(*path));
+-}
+ bool EndsWithSeparator(const std::wstring& path) {
+   return EndsWithSeparator(FilePath::FromWStringHack(path));
+ }
+-bool GetCurrentDirectory(std::wstring* path_str) {
+-  FilePath path;
+-  if (!GetCurrentDirectory(&path))
+-    return false;
+-  *path_str = path.ToWStringHack();
+-  return true;
+-}
+ std::wstring GetFileExtensionFromPath(const std::wstring& path) {
+   FilePath::StringType extension =
+       GetFileExtensionFromPath(FilePath::FromWStringHack(path));
+@@ -370,44 +386,18 @@ std::wstring GetFileExtensionFromPath(const std::wstring& path) {
+   return UTF8ToWide(extension);
+ #endif
+ }
+-bool GetFileInfo(const std::wstring& file_path, FileInfo* results) {
+-  return GetFileInfo(FilePath::FromWStringHack(file_path), results);
+-}
+ std::wstring GetFilenameFromPath(const std::wstring& path) {
+   if (path.empty() || EndsWithSeparator(path))
+     return std::wstring();
+ 
+   return FilePath::FromWStringHack(path).BaseName().ToWStringHack();
+ }
+-bool GetFileSize(const std::wstring& file_path, int64* file_size) {
+-  return GetFileSize(FilePath::FromWStringHack(file_path), file_size);
+-}
+-bool GetTempDir(std::wstring* path_str) {
+-  FilePath path;
+-  if (!GetTempDir(&path))
+-    return false;
+-  *path_str = path.ToWStringHack();
+-  return true;
+-}
+-bool Move(const std::wstring& from_path, const std::wstring& to_path) {
+-  return Move(FilePath::FromWStringHack(from_path),
+-              FilePath::FromWStringHack(to_path));
+-}
+ FILE* OpenFile(const std::wstring& filename, const char* mode) {
+   return OpenFile(FilePath::FromWStringHack(filename), mode);
+ }
+-bool PathExists(const std::wstring& path) {
+-  return PathExists(FilePath::FromWStringHack(path));
+-}
+-bool PathIsWritable(const std::wstring& path) {
+-  return PathIsWritable(FilePath::FromWStringHack(path));
+-}
+ int ReadFile(const std::wstring& filename, char* data, int size) {
+   return ReadFile(FilePath::FromWStringHack(filename), data, size);
+ }
+-bool SetCurrentDirectory(const std::wstring& directory) {
+-  return SetCurrentDirectory(FilePath::FromWStringHack(directory));
+-}
+ void UpOneDirectory(std::wstring* dir) {
+   FilePath path = FilePath::FromWStringHack(*dir);
+   FilePath directory = path.DirName();
+@@ -429,4 +419,15 @@ void UpOneDirectoryOrEmpty(std::wstring* dir) {
+ int WriteFile(const std::wstring& filename, const char* data, int size) {
+   return WriteFile(FilePath::FromWStringHack(filename), data, size);
+ }
++
++///////////////////////////////////////////////
++// FileEnumerator
++//
++// Note: the main logic is in file_util_<platform>.cc
++
++bool FileEnumerator::ShouldSkip(const FilePath& path) {
++  FilePath::StringType basename = path.BaseName().value();
++  return IsDot(path) || (IsDotDot(path) && !(INCLUDE_DOT_DOT & file_type_));
++}
++
+ }  // namespace
+diff --git a/ipc/chromium/src/base/file_util.h b/ipc/chromium/src/base/file_util.h
+index 5226768..f142cba 100644
+--- a/ipc/chromium/src/base/file_util.h
++++ b/ipc/chromium/src/base/file_util.h
+@@ -1,4 +1,4 @@
+-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
++// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style license that can be
+ // found in the LICENSE file.
+ 
+@@ -12,7 +12,7 @@
+ 
+ #if defined(OS_WIN)
+ #include <windows.h>
+-#elif defined(ANDROID)
++#elif defined(ANDROID) || defined(OS_SOLARIS)
+ #include <sys/stat.h>
+ #elif defined(OS_POSIX) 
+ #include <fts.h>
+@@ -26,8 +26,18 @@
+ #include <vector>
+ 
+ #include "base/basictypes.h"
+-#include "base/scoped_ptr.h"
+ #include "base/file_path.h"
++#include "base/platform_file.h"
++#include "base/scoped_ptr.h"
++#include "base/string16.h"
++#include "base/time.h"
++
++#include "unistd.h"
++
++#if defined(OS_POSIX)
++#include "base/eintr_wrapper.h"
++#include "base/file_descriptor_posix.h"
++#endif
+ 
+ namespace base {
+ class Time;
+@@ -38,99 +48,25 @@ namespace file_util {
+ //-----------------------------------------------------------------------------
+ // Functions that operate purely on a path string w/o touching the filesystem:
+ 
+-// Returns a vector of all of the components of the provided path.
+-void PathComponents(const FilePath& path,
+-                    std::vector<FilePath::StringType>* components);
+-#if defined(OS_WIN)
+-// Deprecated temporary compatibility function.
+-void PathComponents(const std::wstring& path,
+-                    std::vector<std::wstring>* components);
+-#endif
+-
+ // Returns true if the given path ends with a path separator character.
+ bool EndsWithSeparator(const FilePath& path);
+-// These two versions are both deprecated. TODO(estade): remove them.
+-bool EndsWithSeparator(std::wstring* path);
+-bool EndsWithSeparator(const std::wstring& path);
+ 
+ // Makes sure that |path| ends with a separator IFF path is a directory that
+ // exists. Returns true if |path| is an existing directory, false otherwise.
+ bool EnsureEndsWithSeparator(FilePath* path);
+ 
+-// Modifies a string by trimming all trailing separators from the end.
+-// Deprecated. FilePath does this automatically, and if it's constructed from a
+-// path with a trailing separator, StripTrailingSeparators() may be used.
+-void TrimTrailingSeparator(std::wstring* dir);
+-
+-// Strips the topmost directory from the end of 'dir'.  Assumes 'dir' does not
+-// refer to a file.
+-// If 'dir' is a root directory, return without change.
+-// Deprecated. Use FilePath::DirName instead.
+-void UpOneDirectory(std::wstring* dir);
+-// Strips the topmost directory from the end of 'dir'.  Assumes 'dir' does not
+-// refer to a file.
+-// If 'dir' is a root directory, the result becomes empty string.
+-// Deprecated. Use FilePath::DirName instead.
+-void UpOneDirectoryOrEmpty(std::wstring* dir);
+-
+-// Returns the filename portion of 'path', without any leading \'s or /'s.
+-// Deprecated. Use FilePath::BaseName instead.
+-std::wstring GetFilenameFromPath(const std::wstring& path);
+-
+-// Deprecated compatibility function.  Use FilePath::Extension.
+-FilePath::StringType GetFileExtensionFromPath(const FilePath& path);
+-// Deprecated temporary compatibility function.
+-std::wstring GetFileExtensionFromPath(const std::wstring& path);
+-
+-// Returns the directory component of a path, without the trailing
+-// path separator, or an empty string on error. The function does not
+-// check for the existence of the path, so if it is passed a directory
+-// without the trailing \, it will interpret the last component of the
+-// path as a file and chomp it. This does not support relative paths.
+-// Examples:
+-// path == "C:\pics\jojo.jpg",     returns "C:\pics"
+-// path == "C:\Windows\system32\", returns "C:\Windows\system32"
+-// path == "C:\Windows\system32",  returns "C:\Windows"
+-std::wstring GetDirectoryFromPath(const std::wstring& path);
+-
+-// Appends new_ending to path, adding a separator between the two if necessary.
+-void AppendToPath(std::wstring* path, const std::wstring& new_ending);
+-
+ // Convert provided relative path into an absolute path.  Returns false on
+ // error. On POSIX, this function fails if the path does not exist.
+ bool AbsolutePath(FilePath* path);
+-// Deprecated temporary compatibility function.
+-bool AbsolutePath(std::wstring* path);
+ 
+ // Returns true if |parent| contains |child|. Both paths are converted to
+ // absolute paths before doing the comparison.
+ bool ContainsPath(const FilePath& parent, const FilePath& child);
+ 
+-// Deprecated compatibility function.  Use FilePath::InsertBeforeExtension.
+-void InsertBeforeExtension(FilePath* path, const FilePath::StringType& suffix);
+-
+-// Deprecated compatibility function.  Use FilePath::ReplaceExtension.
+-void ReplaceExtension(FilePath* file_name,
+-                      const FilePath::StringType& extension);
+-
+-#if defined(OS_WIN)
+-// Deprecated temporary compatibility functions.
+-void InsertBeforeExtension(std::wstring* path, const std::wstring& suffix);
+-void ReplaceExtension(std::wstring* file_name, const std::wstring& extension);
+-#endif
+-
+-// Replaces characters in 'file_name' that are illegal for file names with
+-// 'replace_char'. 'file_name' must not be a full or relative path, but just the
+-// file name component. Any leading or trailing whitespace in 'file_name' is
+-// removed.
+-// Example:
+-//   file_name == "bad:file*name?.txt", changed to: "bad-file-name-.txt" when
+-//   'replace_char' is '-'.
+-void ReplaceIllegalCharacters(std::wstring* file_name, int replace_char);
+-
+ //-----------------------------------------------------------------------------
+ // Functions that involve filesystem access or modification:
+ 
++// Returns the number of files matching the current path that were
+ // created on or after the given |file_time|.  Doesn't count ".." or ".".
+ //
+ // Note for POSIX environments: a file created before |file_time|
+@@ -141,6 +77,13 @@ void ReplaceIllegalCharacters(std::wstring* file_name, int replace_char);
+ int CountFilesCreatedAfter(const FilePath& path,
+                            const base::Time& file_time);
+ 
++// Returns the total number of bytes used by all the files under |root_path|.
++// If the path does not exist the function returns 0.
++//
++// This function is implemented using the FileEnumerator class so it is not
++// particularly speedy in any platform.
++int64 ComputeDirectorySize(const FilePath& root_path);
++
+ // Deletes the given path, whether it's a file or a directory.
+ // If it's a directory, it's perfectly happy to delete all of the
+ // directory's contents.  Passing true to recursive deletes
+@@ -150,50 +93,51 @@ int CountFilesCreatedAfter(const FilePath& path,
+ // WARNING: USING THIS WITH recursive==true IS EQUIVALENT
+ //          TO "rm -rf", SO USE WITH CAUTION.
+ bool Delete(const FilePath& path, bool recursive);
+-// Deprecated temporary compatibility function.
+-bool Delete(const std::wstring& path, bool recursive);
++
++#if defined(OS_WIN)
++// Schedules to delete the given path, whether it's a file or a directory, until
++// the operating system is restarted.
++// Note:
++// 1) The file/directory to be deleted should exist in a temp folder.
++// 2) The directory to be deleted must be empty.
++bool DeleteAfterReboot(const FilePath& path);
++#endif
+ 
+ // Moves the given path, whether it's a file or a directory.
+ // If a simple rename is not possible, such as in the case where the paths are
+ // on different volumes, this will attempt to copy and delete. Returns
+ // true for success.
+ bool Move(const FilePath& from_path, const FilePath& to_path);
+-// Deprecated temporary compatibility function.
+-bool Move(const std::wstring& from_path, const std::wstring& to_path);
++
++// Renames file |from_path| to |to_path|. Both paths must be on the same
++// volume, or the function will fail. Destination file will be created
++// if it doesn't exist. Prefer this function over Move when dealing with
++// temporary files. On Windows it preserves attributes of the target file.
++// Returns true on success.
++bool ReplaceFile(const FilePath& from_path, const FilePath& to_path);
+ 
+ // Copies a single file. Use CopyDirectory to copy directories.
+ bool CopyFile(const FilePath& from_path, const FilePath& to_path);
+-// Deprecated temporary compatibility function.
+-bool CopyFile(const std::wstring& from_path, const std::wstring& to_path);
+ 
+ // Copies the given path, and optionally all subdirectories and their contents
+ // as well.
+ // If there are files existing under to_path, always overwrite.
+ // Returns true if successful, false otherwise.
+-// Dont't use wildcards on the names, it may stop working without notice.
++// Don't use wildcards on the names, it may stop working without notice.
+ //
+ // If you only need to copy a file use CopyFile, it's faster.
+ bool CopyDirectory(const FilePath& from_path, const FilePath& to_path,
+                    bool recursive);
+-// Deprecated temporary compatibility function.
+-bool CopyDirectory(const std::wstring& from_path, const std::wstring& to_path,
+-                   bool recursive);
+ 
+ // Returns true if the given path exists on the local filesystem,
+ // false otherwise.
+ bool PathExists(const FilePath& path);
+-// Deprecated temporary compatibility function.
+-bool PathExists(const std::wstring& path);
+ 
+ // Returns true if the given path is writable by the user, false otherwise.
+ bool PathIsWritable(const FilePath& path);
+-// Deprecated temporary compatibility function.
+-bool PathIsWritable(const std::wstring& path);
+ 
+ // Returns true if the given path exists and is a directory, false otherwise.
+ bool DirectoryExists(const FilePath& path);
+-// Deprecated temporary compatibility function.
+-bool DirectoryExists(const std::wstring& path);
+ 
+ #if defined(OS_WIN)
+ // Gets the creation time of the given file (expressed in the local timezone),
+@@ -211,15 +155,14 @@ bool GetFileCreationLocalTimeFromHandle(HANDLE file_handle,
+ // otherwise.  If either file can't be read, returns false.
+ bool ContentsEqual(const FilePath& filename1,
+                    const FilePath& filename2);
+-// Deprecated temporary compatibility function.
+-bool ContentsEqual(const std::wstring& filename1,
+-                   const std::wstring& filename2);
++
++// Returns true if the contents of the two text files given are equal, false
++// otherwise.  This routine treats "\r\n" and "\n" as equivalent.
++bool TextContentsEqual(const FilePath& filename1, const FilePath& filename2);
+ 
+ // Read the file at |path| into |contents|, returning true on success.
+ // Useful for unit tests.
+ bool ReadFileToString(const FilePath& path, std::string* contents);
+-// Deprecated version.
+-bool ReadFileToString(const std::wstring& path, std::string* contents);
+ 
+ #if defined(OS_POSIX)
+ // Read exactly |bytes| bytes from file descriptor |fd|, storing the result
+@@ -230,11 +173,10 @@ bool ReadFromFD(int fd, char* buffer, size_t bytes);
+ 
+ #if defined(OS_WIN)
+ // Resolve Windows shortcut (.LNK file)
+-// Argument path specifies a valid LNK file. On success, return true and put
+-// the URL into path. If path is a invalid .LNK file, return false.
++// This methods tries to resolve a shortcut .LNK file. If the |path| is valid
++// returns true and puts the target into the |path|, otherwise returns
++// false leaving the path as it is.
+ bool ResolveShortcut(FilePath* path);
+-// Deprecated temporary compatibility function.
+-bool ResolveShortcut(std::wstring* path);
+ 
+ // Create a Windows shortcut (.LNK file)
+ // This method creates a shortcut link using the information given. Ensure
+@@ -243,24 +185,32 @@ bool ResolveShortcut(std::wstring* path);
+ // 'source' is the existing file, 'destination' is the new link file to be
+ // created; for best results pass the filename with the .lnk extension.
+ // The 'icon' can specify a dll or exe in which case the icon index is the
+-// resource id.
++// resource id. 'app_id' is the app model id for the shortcut on Win7.
+ // Note that if the shortcut exists it will overwrite it.
+ bool CreateShortcutLink(const wchar_t *source, const wchar_t *destination,
+                         const wchar_t *working_dir, const wchar_t *arguments,
+                         const wchar_t *description, const wchar_t *icon,
+-                        int icon_index);
++                        int icon_index, const wchar_t* app_id);
+ 
+ // Update a Windows shortcut (.LNK file). This method assumes the shortcut
+ // link already exists (otherwise false is returned). Ensure you have
+ // initialized COM before calling into this function. Only 'destination'
+ // parameter is required, everything else can be NULL (but if everything else
+ // is NULL no changes are made to the shortcut). 'destination' is the link
+-// file to be updated. For best results pass the filename with the .lnk
+-// extension.
++// file to be updated. 'app_id' is the app model id for the shortcut on Win7.
++// For best results pass the filename with the .lnk extension.
+ bool UpdateShortcutLink(const wchar_t *source, const wchar_t *destination,
+                         const wchar_t *working_dir, const wchar_t *arguments,
+                         const wchar_t *description, const wchar_t *icon,
+-                        int icon_index);
++                        int icon_index, const wchar_t* app_id);
++
++// Pins a shortcut to the Windows 7 taskbar. The shortcut file must already
++// exist and be a shortcut that points to an executable.
++bool TaskbarPinShortcutLink(const wchar_t* shortcut);
++
++// Unpins a shortcut from the Windows 7 taskbar. The shortcut must exist and
++// already be pinned to the taskbar.
++bool TaskbarUnpinShortcutLink(const wchar_t* shortcut);
+ 
+ // Return true if the given directory is empty
+ bool IsDirectoryEmpty(const std::wstring& dir_path);
+@@ -275,21 +225,18 @@ bool CopyAndDeleteDirectory(const FilePath& from_path,
+ 
+ // Get the temporary directory provided by the system.
+ bool GetTempDir(FilePath* path);
+-// Deprecated temporary compatibility function.
+-bool GetTempDir(std::wstring* path);
+ // Get a temporary directory for shared memory files.
+ // Only useful on POSIX; redirects to GetTempDir() on Windows.
+ bool GetShmemTempDir(FilePath* path);
+ 
++// Get the home directory.  This is more complicated than just getenv("HOME")
++// as it knows to fall back on getpwent() etc.
++FilePath GetHomeDir();
++
+ // Creates a temporary file. The full path is placed in |path|, and the
+ // function returns true if was successful in creating the file. The file will
+ // be empty and all handles closed after this function returns.
+-// TODO(erikkay): rename this function and track down all of the callers.
+-// (Clarification of erik's comment: the intent is to rename the BlahFileName()
+-//  calls into BlahFile(), since they create temp files (not temp filenames).)
+-bool CreateTemporaryFileName(FilePath* path);
+-// Deprecated temporary compatibility function.
+-bool CreateTemporaryFileName(std::wstring* temp_file);
++bool CreateTemporaryFile(FilePath* path);
+ 
+ // Create and open a temporary file.  File is opened for read/write.
+ // The full path is placed in |path|, and the function returns true if
+@@ -301,9 +248,16 @@ FILE* CreateAndOpenTemporaryShmemFile(FilePath* path);
+ // Similar to CreateAndOpenTemporaryFile, but the file is created in |dir|.
+ FILE* CreateAndOpenTemporaryFileInDir(const FilePath& dir, FilePath* path);
+ 
+-// Same as CreateTemporaryFileName but the file is created in |dir|.
+-bool CreateTemporaryFileNameInDir(const std::wstring& dir,
+-                                  std::wstring* temp_file);
++// Same as CreateTemporaryFile but the file is created in |dir|.
++bool CreateTemporaryFileInDir(const FilePath& dir,
++                              FilePath* temp_file);
++
++// Create a directory within another directory.
++// Extra characters will be appended to |name_tmpl| to ensure that the
++// new directory does not have the same name as an existing directory.
++bool CreateTemporaryDirInDir(const FilePath& base_dir,
++                             const FilePath::StringType& prefix,
++                             FilePath* new_dir);
+ 
+ // Create a new directory under TempPath. If prefix is provided, the new
+ // directory name is in the format of prefixyyyy.
+@@ -312,21 +266,20 @@ bool CreateTemporaryFileNameInDir(const std::wstring& dir,
+ // If success, return true and output the full path of the directory created.
+ bool CreateNewTempDirectory(const FilePath::StringType& prefix,
+                             FilePath* new_temp_path);
+-// Deprecated temporary compatibility function.
+-bool CreateNewTempDirectory(const std::wstring& prefix,
+-                            std::wstring* new_temp_path);
+ 
+ // Creates a directory, as well as creating any parent directories, if they
+ // don't exist. Returns 'true' on successful creation, or if the directory
+-// already exists.
++// already exists.  The directory is only readable by the current user.
+ bool CreateDirectory(const FilePath& full_path);
+-// Deprecated temporary compatibility function.
+-bool CreateDirectory(const std::wstring& full_path);
+ 
+ // Returns the file size. Returns true on success.
+ bool GetFileSize(const FilePath& file_path, int64* file_size);
+-// Deprecated temporary compatibility function.
+-bool GetFileSize(const std::wstring& file_path, int64* file_size);
++
++// Returns true if the given path's base name is ".".
++bool IsDot(const FilePath& path);
++
++// Returns true if the given path's base name is "..".
++bool IsDotDot(const FilePath& path);
+ 
+ // Used to hold information about a given file path.  See GetFileInfo below.
+ struct FileInfo {
+@@ -336,19 +289,25 @@ struct FileInfo {
+   // True if the file corresponds to a directory.
+   bool is_directory;
+ 
++  // The last modified time of a file.
++  base::Time last_modified;
++
+   // Add additional fields here as needed.
+ };
+ 
+ // Returns information about the given file path.
+ bool GetFileInfo(const FilePath& file_path, FileInfo* info);
+-// Deprecated temporary compatibility function.
+-bool GetFileInfo(const std::wstring& file_path, FileInfo* info);
++
++// Set the time of the last modification. Useful for unit tests.
++bool SetLastModifiedTime(const FilePath& file_path, base::Time last_modified);
++
++#if defined(OS_POSIX)
++// Store inode number of |path| in |inode|. Return true on success.
++bool GetInode(const FilePath& path, ino_t* inode);
++#endif
+ 
+ // Wrapper for fopen-like calls. Returns non-NULL FILE* on success.
+ FILE* OpenFile(const FilePath& filename, const char* mode);
+-// Deprecated temporary compatibility functions.
+-FILE* OpenFile(const std::string& filename, const char* mode);
+-FILE* OpenFile(const std::wstring& filename, const char* mode);
+ 
+ // Closes file opened by OpenFile. Returns true on success.
+ bool CloseFile(FILE* file);
+@@ -360,24 +319,20 @@ bool TruncateFile(FILE* file);
+ // Reads the given number of bytes from the file into the buffer.  Returns
+ // the number of read bytes, or -1 on error.
+ int ReadFile(const FilePath& filename, char* data, int size);
+-// Deprecated temporary compatibility function.
+-int ReadFile(const std::wstring& filename, char* data, int size);
+ 
+ // Writes the given buffer into the file, overwriting any data that was
+ // previously there.  Returns the number of bytes written, or -1 on error.
+ int WriteFile(const FilePath& filename, const char* data, int size);
+-// Deprecated temporary compatibility function.
+-int WriteFile(const std::wstring& filename, const char* data, int size);
++#if defined(OS_POSIX)
++// Append the data to |fd|. Does not close |fd| when done.
++int WriteFileDescriptor(const int fd, const char* data, int size);
++#endif
+ 
+ // Gets the current working directory for the process.
+ bool GetCurrentDirectory(FilePath* path);
+-// Deprecated temporary compatibility function.
+-bool GetCurrentDirectory(std::wstring* path);
+ 
+ // Sets the current working directory for the process.
+ bool SetCurrentDirectory(const FilePath& path);
+-// Deprecated temporary compatibility function.
+-bool SetCurrentDirectory(const std::wstring& current_directory);
+ 
+ // A class to handle auto-closing of FILE*'s.
+ class ScopedFILEClose {
+@@ -391,6 +346,20 @@ class ScopedFILEClose {
+ 
+ typedef scoped_ptr_malloc<FILE, ScopedFILEClose> ScopedFILE;
+ 
++#if defined(OS_POSIX)
++// A class to handle auto-closing of FDs.
++class ScopedFDClose {
++ public:
++  inline void operator()(int* x) const {
++    if (x && *x >= 0) {
++      HANDLE_EINTR(close(*x));
++    }
++  }
++};
++
++typedef scoped_ptr_malloc<int, ScopedFDClose> ScopedFD;
++#endif  // OS_POSIX
++
+ // A class for enumerating the files in a provided path. The order of the
+ // results is not guaranteed.
+ //
+@@ -408,9 +377,12 @@ class FileEnumerator {
+ #endif
+ 
+   enum FILE_TYPE {
+-    FILES                 = 0x1,
+-    DIRECTORIES           = 0x2,
+-    FILES_AND_DIRECTORIES = 0x3
++    FILES                 = 1 << 0,
++    DIRECTORIES           = 1 << 1,
++    INCLUDE_DOT_DOT       = 1 << 2,
++#if defined(OS_POSIX)
++    SHOW_SYM_LINKS        = 1 << 4,
++#endif
+   };
+ 
+   // |root_path| is the starting directory to search for. It may or may not end
+@@ -448,11 +420,40 @@ class FileEnumerator {
+   // Write the file info into |info|.
+   void GetFindInfo(FindInfo* info);
+ 
++  // Looks inside a FindInfo and determines if it's a directory.
++  static bool IsDirectory(const FindInfo& info);
++
++  static FilePath GetFilename(const FindInfo& find_info);
++
+  private:
++  // Returns true if the given path should be skipped in enumeration.
++  bool ShouldSkip(const FilePath& path);
++
++
++#if defined(OS_WIN)
++  WIN32_FIND_DATA find_data_;
++  HANDLE find_handle_;
++#elif defined(OS_POSIX)
++  typedef struct {
++    FilePath filename;
++    struct stat stat;
++  } DirectoryEntryInfo;
++
++  // Read the filenames in source into the vector of DirectoryEntryInfo's
++  static bool ReadDirectory(std::vector<DirectoryEntryInfo>* entries,
++                            const FilePath& source, bool show_links);
++
++  // The files in the current directory
++  std::vector<DirectoryEntryInfo> directory_entries_;
++
++  // The next entry to use from the directory_entries_ vector
++  size_t current_directory_entry_;
++#endif
++
+   FilePath root_path_;
+   bool recursive_;
+   FILE_TYPE file_type_;
+-  FilePath pattern_;  // Empty when we want to find everything.
++  FilePath::StringType pattern_;  // Empty when we want to find everything.
+ 
+   // Set to true when there is a find operation open. This way, we can lazily
+   // start the operations when the caller calls Next().
+@@ -462,17 +463,7 @@ class FileEnumerator {
+   // enumerate in the breadth-first search.
+   std::stack<FilePath> pending_paths_;
+ 
+-#if defined(OS_WIN)
+-  WIN32_FIND_DATA find_data_;
+-  HANDLE find_handle_;
+-#elif defined(ANDROID)
+-  void *fts_;
+-#elif defined(OS_POSIX)
+-  FTS* fts_;
+-  FTSENT* fts_ent_;
+-#endif
+-
+-  DISALLOW_EVIL_CONSTRUCTORS(FileEnumerator);
++  DISALLOW_COPY_AND_ASSIGN(FileEnumerator);
+ };
+ 
+ class MemoryMappedFile {
+@@ -487,6 +478,9 @@ class MemoryMappedFile {
+   // the file does not exist, or the memory mapping fails, it will return false.
+   // Later we may want to allow the user to specify access.
+   bool Initialize(const FilePath& file_name);
++  // As above, but works with an already-opened file. MemoryMappedFile will take
++  // ownership of |file| and close it when done.
++  bool Initialize(base::PlatformFile file);
+ 
+   const uint8* data() const { return data_; }
+   size_t length() const { return length_; }
+@@ -495,19 +489,19 @@ class MemoryMappedFile {
+   bool IsValid();
+ 
+  private:
++  // Open the given file and pass it to MapFileToMemoryInternal().
++  bool MapFileToMemory(const FilePath& file_name);
++
+   // Map the file to memory, set data_ to that memory address. Return true on
+   // success, false on any kind of failure. This is a helper for Initialize().
+-  bool MapFileToMemory(const FilePath& file_name);
++  bool MapFileToMemoryInternal();
+ 
+   // Closes all open handles. Later we may want to make this public.
+   void CloseHandles();
+ 
++  base::PlatformFile file_;
+ #if defined(OS_WIN)
+-  HANDLE file_;
+   HANDLE file_mapping_;
+-#elif defined(OS_POSIX)
+-  // The file descriptor.
+-  int file_;
+ #endif
+   uint8* data_;
+   size_t length_;
+@@ -521,6 +515,66 @@ bool RenameFileAndResetSecurityDescriptor(
+     const FilePath& source_file_path,
+     const FilePath& target_file_path);
+ 
++// Returns whether the file has been modified since a particular date.
++bool HasFileBeenModifiedSince(const FileEnumerator::FindInfo& find_info,
++                              const base::Time& cutoff_time);
++
++#ifdef UNIT_TEST
++
++inline bool MakeFileUnreadable(const FilePath& path) {
++#if defined(OS_POSIX)
++  struct stat stat_buf;
++  if (stat(path.value().c_str(), &stat_buf) != 0)
++    return false;
++  stat_buf.st_mode &= ~(S_IRUSR | S_IRGRP | S_IROTH);
++
++  return chmod(path.value().c_str(), stat_buf.st_mode) == 0;
++
++#elif defined(OS_WIN)
++  PACL old_dacl;
++  PSECURITY_DESCRIPTOR security_descriptor;
++  if (GetNamedSecurityInfo(const_cast<wchar_t*>(path.value().c_str()),
++                           SE_FILE_OBJECT,
++                           DACL_SECURITY_INFORMATION, NULL, NULL, &old_dacl,
++                           NULL, &security_descriptor) != ERROR_SUCCESS)
++    return false;
++
++  // Deny Read access for the current user.
++  EXPLICIT_ACCESS change;
++  change.grfAccessPermissions = GENERIC_READ;
++  change.grfAccessMode = DENY_ACCESS;
++  change.grfInheritance = 0;
++  change.Trustee.pMultipleTrustee = NULL;
++  change.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
++  change.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
++  change.Trustee.TrusteeType = TRUSTEE_IS_USER;
++  change.Trustee.ptstrName = L"CURRENT_USER";
++
++  PACL new_dacl;
++  if (SetEntriesInAcl(1, &change, old_dacl, &new_dacl) != ERROR_SUCCESS) {
++    LocalFree(security_descriptor);
++    return false;
++  }
++
++  DWORD rc = SetNamedSecurityInfo(const_cast<wchar_t*>(path.value().c_str()),
++                                  SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
++                                  NULL, NULL, new_dacl, NULL);
++  LocalFree(security_descriptor);
++  LocalFree(new_dacl);
++
++  return rc == ERROR_SUCCESS;
++#else
++  NOTIMPLEMENTED();
++  return false;
++#endif
++}
++
++#endif  // UNIT_TEST
++
+ }  // namespace file_util
+ 
++// Deprecated functions have been moved to this separate header file,
++// which must be included last after all the above definitions.
++#include "base/file_util_deprecated.h"
++
+ #endif  // BASE_FILE_UTIL_H_
+diff --git a/ipc/chromium/src/base/file_util_posix.cc b/ipc/chromium/src/base/file_util_posix.cc
+index bc07b19..a78c0d3 100644
+--- a/ipc/chromium/src/base/file_util_posix.cc
++++ b/ipc/chromium/src/base/file_util_posix.cc
+@@ -1,4 +1,4 @@
+-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
++// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style license that can be
+ // found in the LICENSE file.
+ 
+@@ -8,48 +8,60 @@
+ #include <errno.h>
+ #include <fcntl.h>
+ #include <fnmatch.h>
+-#ifndef ANDROID
+-#include <fts.h>
+-#endif
+ #include <libgen.h>
+ #include <stdio.h>
++#include <stdlib.h>
+ #include <string.h>
+ #include <sys/errno.h>
+ #include <sys/mman.h>
+ #include <sys/stat.h>
++#include <sys/time.h>
+ #include <sys/types.h>
+ #include <time.h>
+ #include <unistd.h>
+ 
++#if defined(OS_MACOSX)
++#include <AvailabilityMacros.h>
++#else
++#include <glib.h>
++#endif
++
+ #include <fstream>
+ 
+ #include "base/basictypes.h"
+ #include "base/eintr_wrapper.h"
+ #include "base/file_path.h"
++#include "base/lock.h"
+ #include "base/logging.h"
++#include "base/scoped_ptr.h"
++#include "base/singleton.h"
+ #include "base/string_util.h"
++#include "base/sys_string_conversions.h"
+ #include "base/time.h"
+ 
+ namespace file_util {
+ 
++#if defined(OS_OPENBSD) || defined(OS_FREEBSD) || \
++    (defined(OS_MACOSX) && \
++     MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5)
++typedef struct stat stat_wrapper_t;
++static int CallStat(const char *path, stat_wrapper_t *sb) {
++  return stat(path, sb);
++}
++#else
++typedef struct stat64 stat_wrapper_t;
++static int CallStat(const char *path, stat_wrapper_t *sb) {
++  return stat64(path, sb);
++}
++#endif
++
++
+ #if defined(GOOGLE_CHROME_BUILD)
+ static const char* kTempFileName = "com.google.chrome.XXXXXX";
+ #else
+ static const char* kTempFileName = "org.chromium.XXXXXX";
+ #endif
+ 
+-std::wstring GetDirectoryFromPath(const std::wstring& path) {
+-  if (EndsWithSeparator(path)) {
+-    std::wstring dir = path;
+-    TrimTrailingSeparator(&dir);
+-    return dir;
+-  } else {
+-    char full_path[PATH_MAX];
+-    base::strlcpy(full_path, WideToUTF8(path).c_str(), arraysize(full_path));
+-    return UTF8ToWide(dirname(full_path));
+-  }
+-}
+-
+ bool AbsolutePath(FilePath* path) {
+   char full_path[PATH_MAX];
+   if (realpath(path->value().c_str(), full_path) == NULL)
+@@ -64,17 +76,30 @@ int CountFilesCreatedAfter(const FilePath& path,
+ 
+   DIR* dir = opendir(path.value().c_str());
+   if (dir) {
++#if !defined(OS_LINUX) && !defined(OS_MACOSX) && !defined(OS_FREEBSD) && \
++    !defined(OS_OPENBSD) && !defined(OS_SOLARIS)
++  #error Port warning: depending on the definition of struct dirent, \
++         additional space for pathname may be needed
++#endif
++
++#ifdef OS_SOLARIS    
++    struct {
++            dirent dent_buffer;
++            char chars[MAXNAMLEN];
++    } ent_buf;
++#else  
+     struct dirent ent_buf;
++#endif  
+     struct dirent* ent;
+-    while (readdir_r(dir, &ent_buf, &ent) == 0 && ent) {
++    while (readdir_r(dir, (dirent *)&ent_buf, &ent) == 0 && ent) {
+       if ((strcmp(ent->d_name, ".") == 0) ||
+           (strcmp(ent->d_name, "..") == 0))
+         continue;
+ 
+-      struct stat64 st;
+-      int test = stat64(path.Append(ent->d_name).value().c_str(), &st);
++      stat_wrapper_t st;
++      int test = CallStat(path.Append(ent->d_name).value().c_str(), &st);
+       if (test != 0) {
+-        LOG(ERROR) << "stat64 failed: " << strerror(errno);
++        LOG(ERROR) << "stat64 failed";
+         continue;
+       }
+       // Here, we use Time::TimeT(), which discards microseconds. This
+@@ -106,8 +131,8 @@ int CountFilesCreatedAfter(const FilePath& path,
+ // here.
+ bool Delete(const FilePath& path, bool recursive) {
+   const char* path_str = path.value().c_str();
+-  struct stat64 file_info;
+-  int test = stat64(path_str, &file_info);
++  stat_wrapper_t file_info;
++  int test = CallStat(path_str, &file_info);
+   if (test != 0) {
+     // The Windows version defines this condition as success.
+     bool ret = (errno == ENOENT || errno == ENOTDIR);
+@@ -118,53 +143,46 @@ bool Delete(const FilePath& path, bool recursive) {
+   if (!recursive)
+     return (rmdir(path_str) == 0);
+ 
+-#ifdef ANDROID
+-  // XXX Need ftsless impl for bionic
+-  return false;
+-#else
+   bool success = true;
+-  int ftsflags = FTS_PHYSICAL | FTS_NOSTAT;
+-  char top_dir[PATH_MAX];
+-  if (base::strlcpy(top_dir, path_str,
+-                    arraysize(top_dir)) >= arraysize(top_dir)) {
+-    return false;
++  std::stack<std::string> directories;
++  directories.push(path.value());
++  FileEnumerator traversal(path, true, static_cast<FileEnumerator::FILE_TYPE>(
++        FileEnumerator::FILES | FileEnumerator::DIRECTORIES |
++        FileEnumerator::SHOW_SYM_LINKS));
++  for (FilePath current = traversal.Next(); success && !current.empty();
++       current = traversal.Next()) {
++    FileEnumerator::FindInfo info;
++    traversal.GetFindInfo(&info);
++
++    if (S_ISDIR(info.stat.st_mode))
++      directories.push(current.value());
++    else
++      success = (unlink(current.value().c_str()) == 0);
+   }
+-  char* dir_list[2] = { top_dir, NULL };
+-  FTS* fts = fts_open(dir_list, ftsflags, NULL);
+-  if (fts) {
+-    FTSENT* fts_ent = fts_read(fts);
+-    while (success && fts_ent != NULL) {
+-      switch (fts_ent->fts_info) {
+-        case FTS_DNR:
+-        case FTS_ERR:
+-          // log error
+-          success = false;
+-          continue;
+-          break;
+-        case FTS_DP:
+-          success = (rmdir(fts_ent->fts_accpath) == 0);
+-          break;
+-        case FTS_D:
+-          break;
+-        case FTS_NSOK:
+-        case FTS_F:
+-        case FTS_SL:
+-        case FTS_SLNONE:
+-          success = (unlink(fts_ent->fts_accpath) == 0);
+-          break;
+-        default:
+-          DCHECK(false);
+-          break;
+-      }
+-      fts_ent = fts_read(fts);
+-    }
+-    fts_close(fts);
++
++  while (success && !directories.empty()) {
++    FilePath dir = FilePath(directories.top());
++    directories.pop();
++    success = (rmdir(dir.value().c_str()) == 0);
+   }
++
+   return success;
+-#endif
+ }
+ 
+ bool Move(const FilePath& from_path, const FilePath& to_path) {
++  // Windows compatibility: if to_path exists, from_path and to_path
++  // must be the same type, either both files, or both directories.
++  stat_wrapper_t to_file_info;
++  if (CallStat(to_path.value().c_str(), &to_file_info) == 0) {
++    stat_wrapper_t from_file_info;
++    if (CallStat(from_path.value().c_str(), &from_file_info) == 0) {
++      if (S_ISDIR(to_file_info.st_mode) != S_ISDIR(from_file_info.st_mode))
++        return false;
++    } else {
++      return false;
++    }
++  }
++
+   if (rename(from_path.value().c_str(), to_path.value().c_str()) == 0)
+     return true;
+ 
+@@ -175,6 +193,10 @@ bool Move(const FilePath& from_path, const FilePath& to_path) {
+   return true;
+ }
+ 
++bool ReplaceFile(const FilePath& from_path, const FilePath& to_path) {
++  return (rename(from_path.value().c_str(), to_path.value().c_str()) == 0);
++}
++
+ bool CopyDirectory(const FilePath& from_path,
+                    const FilePath& to_path,
+                    bool recursive) {
+@@ -191,116 +213,101 @@ bool CopyDirectory(const FilePath& from_path,
+     return false;
+   }
+ 
+-#ifdef ANDROID
+-  // XXX Need ftsless impl for bionic
+-  return false;
+-#else
+-  char* dir_list[] = { top_dir, NULL };
+-  FTS* fts = fts_open(dir_list, FTS_PHYSICAL | FTS_NOSTAT, NULL);
+-  if (!fts) {
+-    LOG(ERROR) << "fts_open failed: " << strerror(errno);
++  // This function does not properly handle destinations within the source
++  FilePath real_to_path = to_path;
++  if (PathExists(real_to_path)) {
++    if (!AbsolutePath(&real_to_path))
++      return false;
++  } else {
++    real_to_path = real_to_path.DirName();
++    if (!AbsolutePath(&real_to_path))
++      return false;
++  }
++  FilePath real_from_path = from_path;
++  if (!AbsolutePath(&real_from_path))
++    return false;
++  if (real_to_path.value().size() >= real_from_path.value().size() &&
++      real_to_path.value().compare(0, real_from_path.value().size(),
++      real_from_path.value()) == 0)
+     return false;
++
++  bool success = true;
++  FileEnumerator::FILE_TYPE traverse_type =
++      static_cast<FileEnumerator::FILE_TYPE>(FileEnumerator::FILES |
++      FileEnumerator::SHOW_SYM_LINKS);
++  if (recursive)
++    traverse_type = static_cast<FileEnumerator::FILE_TYPE>(
++        traverse_type | FileEnumerator::DIRECTORIES);
++  FileEnumerator traversal(from_path, recursive, traverse_type);
++
++  // We have to mimic windows behavior here. |to_path| may not exist yet,
++  // start the loop with |to_path|.
++  FileEnumerator::FindInfo info;
++  FilePath current = from_path;
++  if (stat(from_path.value().c_str(), &info.stat) < 0) {
++    LOG(ERROR) << "CopyDirectory() couldn't stat source directory: " <<
++        from_path.value() << " errno = " << errno;
++    success = false;
++  }
++  struct stat to_path_stat;
++  FilePath from_path_base = from_path;
++  if (recursive && stat(to_path.value().c_str(), &to_path_stat) == 0 &&
++      S_ISDIR(to_path_stat.st_mode)) {
++    // If the destination already exists and is a directory, then the
++    // top level of source needs to be copied.
++    from_path_base = from_path.DirName();
+   }
+ 
+-  int error = 0;
+-  FTSENT* ent;
+-  while (!error && (ent = fts_read(fts)) != NULL) {
+-    // ent->fts_path is the source path, including from_path, so paste
++  // The Windows version of this function assumes that non-recursive calls
++  // will always have a directory for from_path.
++  DCHECK(recursive || S_ISDIR(info.stat.st_mode));
++
++  while (success && !current.empty()) {
++    // current is the source path, including from_path, so paste
+     // the suffix after from_path onto to_path to create the target_path.
+-    std::string suffix(&ent->fts_path[from_path.value().size()]);
++    std::string suffix(&current.value().c_str()[from_path_base.value().size()]);
+     // Strip the leading '/' (if any).
+     if (!suffix.empty()) {
+       DCHECK_EQ('/', suffix[0]);
+       suffix.erase(0, 1);
+     }
+     const FilePath target_path = to_path.Append(suffix);
+-    switch (ent->fts_info) {
+-      case FTS_D:  // Preorder directory.
+-        // If we encounter a subdirectory in a non-recursive copy, prune it
+-        // from the traversal.
+-        if (!recursive && ent->fts_level > 0) {
+-          if (fts_set(fts, ent, FTS_SKIP) != 0)
+-            error = errno;
+-          continue;
+-        }
+-
+-        // Try creating the target dir, continuing on it if it exists already.
+-        // Rely on the user's umask to produce correct permissions.
+-        if (mkdir(target_path.value().c_str(), 0777) != 0) {
+-          if (errno != EEXIST)
+-            error = errno;
+-        }
+-        break;
+-      case FTS_F:     // Regular file.
+-      case FTS_NSOK:  // File, no stat info requested.
+-        errno = 0;
+-        if (!CopyFile(FilePath(ent->fts_path), target_path))
+-          error = errno ? errno : EINVAL;
+-        break;
+-      case FTS_DP:   // Postorder directory.
+-      case FTS_DOT:  // "." or ".."
+-        // Skip it.
+-        continue;
+-      case FTS_DC:   // Directory causing a cycle.
+-        // Skip this branch.
+-        if (fts_set(fts, ent, FTS_SKIP) != 0)
+-          error = errno;
+-        break;
+-      case FTS_DNR:  // Directory cannot be read.
+-      case FTS_ERR:  // Error.
+-      case FTS_NS:   // Stat failed.
+-        // Abort with the error.
+-        error = ent->fts_errno;
+-        break;
+-      case FTS_SL:      // Symlink.
+-      case FTS_SLNONE:  // Symlink with broken target.
+-        LOG(WARNING) << "CopyDirectory() skipping symbolic link: " <<
+-            ent->fts_path;
+-        continue;
+-      case FTS_DEFAULT:  // Some other sort of file.
+-        LOG(WARNING) << "CopyDirectory() skipping file of unknown type: " <<
+-            ent->fts_path;
+-        continue;
+-      default:
+-        NOTREACHED();
+-        continue;  // Hope for the best!
++
++    if (S_ISDIR(info.stat.st_mode)) {
++      if (mkdir(target_path.value().c_str(), info.stat.st_mode & 01777) != 0 &&
++          errno != EEXIST) {
++        LOG(ERROR) << "CopyDirectory() couldn't create directory: " <<
++            target_path.value() << " errno = " << errno;
++        success = false;
++      }
++    } else if (S_ISREG(info.stat.st_mode)) {
++      if (!CopyFile(current, target_path)) {
++        LOG(ERROR) << "CopyDirectory() couldn't create file: " <<
++            target_path.value();
++        success = false;
++      }
++    } else {
++      LOG(WARNING) << "CopyDirectory() skipping non-regular file: " <<
++          current.value();
+     }
+-  }
+-  // fts_read may have returned NULL and set errno to indicate an error.
+-  if (!error && errno != 0)
+-    error = errno;
+-
+-  if (!fts_close(fts)) {
+-    // If we already have an error, let's use that error instead of the error
+-    // fts_close set.
+-    if (!error)
+-      error = errno;
+-  }
+ 
+-  if (error) {
+-    LOG(ERROR) << "CopyDirectory(): " << strerror(error);
+-    return false;
++    current = traversal.Next();
++    traversal.GetFindInfo(&info);
+   }
+-  return true;
+-#endif
++
++  return success;
+ }
+ 
+ bool PathExists(const FilePath& path) {
+-  struct stat64 file_info;
+-  return (stat64(path.value().c_str(), &file_info) == 0);
++  stat_wrapper_t file_info;
++  return CallStat(path.value().c_str(), &file_info) == 0;
+ }
+ 
+ bool PathIsWritable(const FilePath& path) {
+   FilePath test_path(path);
+-  struct stat64 file_info;
+-  if (stat64(test_path.value().c_str(), &file_info) != 0) {
+-    // If the path doesn't exist, test the parent dir.
+-    test_path = test_path.DirName();
+-    // If the parent dir doesn't exist, then return false (the path is not
+-    // directly writable).
+-    if (stat64(test_path.value().c_str(), &file_info) != 0)
+-      return false;
+-  }
++  stat_wrapper_t file_info;
++  if (CallStat(test_path.value().c_str(), &file_info) != 0)
++    return false;
+   if (S_IWOTH & file_info.st_mode)
+     return true;
+   if (getegid() == file_info.st_gid && (S_IWGRP & file_info.st_mode))
+@@ -311,8 +318,8 @@ bool PathIsWritable(const FilePath& path) {
+ }
+ 
+ bool DirectoryExists(const FilePath& path) {
+-  struct stat64 file_info;
+-  if (stat64(path.value().c_str(), &file_info) == 0)
++  stat_wrapper_t file_info;
++  if (CallStat(path.value().c_str(), &file_info) == 0)
+     return S_ISDIR(file_info.st_mode);
+   return false;
+ }
+@@ -358,10 +365,8 @@ bool ReadFromFD(int fd, char* buffer, size_t bytes) {
+ }
+ 
+ // Creates and opens a temporary file in |directory|, returning the
+-// file descriptor.  |path| is set to the temporary file path.
+-// Note TODO(erikkay) comment in header for BlahFileName() calls; the
+-// intent is to rename these files BlahFile() (since they create
+-// files, not filenames).  This function does NOT unlink() the file.
++// file descriptor. |path| is set to the temporary file path.
++// This function does NOT unlink() the file.
+ int CreateAndOpenFdForTemporaryFile(FilePath directory, FilePath* path) {
+   *path = directory.Append(kTempFileName);
+   const std::string& tmpdir_string = path->value();
+@@ -371,7 +376,7 @@ int CreateAndOpenFdForTemporaryFile(FilePath directory, FilePath* path) {
+   return mkstemp(buffer);
+ }
+ 
+-bool CreateTemporaryFileName(FilePath* path) {
++bool CreateTemporaryFile(FilePath* path) {
+   FilePath directory;
+   if (!GetTempDir(&directory))
+     return false;
+@@ -398,33 +403,46 @@ FILE* CreateAndOpenTemporaryFileInDir(const FilePath& dir, FilePath* path) {
+   return fdopen(fd, "a+");
+ }
+ 
+-bool CreateTemporaryFileNameInDir(const std::wstring& dir,
+-                                  std::wstring* temp_file) {
+-  // Not implemented yet.
+-  NOTREACHED();
+-  return false;
++bool CreateTemporaryFileInDir(const FilePath& dir, FilePath* temp_file) {
++  int fd = CreateAndOpenFdForTemporaryFile(dir, temp_file);
++  return ((fd >= 0) && !close(fd));
+ }
+ 
+-bool CreateNewTempDirectory(const FilePath::StringType& prefix,
+-                            FilePath* new_temp_path) {
+-  FilePath tmpdir;
+-  if (!GetTempDir(&tmpdir))
+-    return false;
+-  tmpdir = tmpdir.Append(kTempFileName);
+-  std::string tmpdir_string = tmpdir.value();
++static bool CreateTemporaryDirInDirImpl(const FilePath& base_dir,
++                                        const FilePath::StringType& name_tmpl,
++                                        FilePath* new_dir) {
++  CHECK(name_tmpl.find("XXXXXX") != FilePath::StringType::npos)
++    << "Directory name template must contain \"XXXXXX\".";
++
++  FilePath sub_dir = base_dir.Append(name_tmpl);
++  std::string sub_dir_string = sub_dir.value();
++
+   // this should be OK since mkdtemp just replaces characters in place
+-  char* buffer = const_cast<char*>(tmpdir_string.c_str());
+-#ifdef ANDROID
+-  char* dtemp = NULL;
+-#else
++  char* buffer = const_cast<char*>(sub_dir_string.c_str());
+   char* dtemp = mkdtemp(buffer);
+-#endif
+   if (!dtemp)
+     return false;
+-  *new_temp_path = FilePath(dtemp);
++  *new_dir = FilePath(dtemp);
+   return true;
+ }
+ 
++bool CreateTemporaryDirInDir(const FilePath& base_dir,
++                             const FilePath::StringType& prefix,
++                             FilePath* new_dir) {
++  FilePath::StringType mkdtemp_template = prefix;
++  mkdtemp_template.append(FILE_PATH_LITERAL("XXXXXX"));
++  return CreateTemporaryDirInDirImpl(base_dir, mkdtemp_template, new_dir);
++}
++
++bool CreateNewTempDirectory(const FilePath::StringType& prefix,
++                            FilePath* new_temp_path) {
++  FilePath tmpdir;
++  if (!GetTempDir(&tmpdir))
++    return false;
++
++  return CreateTemporaryDirInDirImpl(tmpdir, kTempFileName, new_temp_path);
++}
++
+ bool CreateDirectory(const FilePath& full_path) {
+   std::vector<FilePath> subpaths;
+ 
+@@ -440,20 +458,44 @@ bool CreateDirectory(const FilePath& full_path) {
+   // Iterate through the parents and create the missing ones.
+   for (std::vector<FilePath>::reverse_iterator i = subpaths.rbegin();
+        i != subpaths.rend(); ++i) {
+-    if (!DirectoryExists(*i)) {
+-      if (mkdir(i->value().c_str(), 0777) != 0)
+-        return false;
+-    }
++    if (DirectoryExists(*i))
++      continue;
++    if (mkdir(i->value().c_str(), 0700) == 0)
++      continue;
++    // Mkdir failed, but it might have failed with EEXIST, or some other error
++    // due to the the directory appearing out of thin air. This can occur if
++    // two processes are trying to create the same file system tree at the same
++    // time. Check to see if it exists and make sure it is a directory.
++    if (!DirectoryExists(*i))
++      return false;
+   }
+   return true;
+ }
+ 
+ bool GetFileInfo(const FilePath& file_path, FileInfo* results) {
+-  struct stat64 file_info;
+-  if (stat64(file_path.value().c_str(), &file_info) != 0)
++  stat_wrapper_t file_info;
++  if (CallStat(file_path.value().c_str(), &file_info) != 0)
+     return false;
+   results->is_directory = S_ISDIR(file_info.st_mode);
+   results->size = file_info.st_size;
++  results->last_modified = base::Time::FromTimeT(file_info.st_mtime);
++  return true;
++}
++
++bool SetLastModifiedTime(const FilePath& file_path, base::Time last_modified) {
++  struct timeval times[2];
++  times[0] = last_modified.ToTimeVal();
++  times[1] = last_modified.ToTimeVal();
++  return (utimes(file_path.value().c_str(), times) == 0);
++}
++
++bool GetInode(const FilePath& path, ino_t* inode) {
++  struct stat buffer;
++  int result = stat(path.value().c_str(), &buffer);
++  if (result < 0)
++    return false;
++
++  *inode = buffer.st_ino;
+   return true;
+ }
+ 
+@@ -470,9 +512,10 @@ int ReadFile(const FilePath& filename, char* data, int size) {
+   if (fd < 0)
+     return -1;
+ 
+-  int ret_value = HANDLE_EINTR(read(fd, data, size));
+-  HANDLE_EINTR(close(fd));
+-  return ret_value;
++  ssize_t bytes_read = HANDLE_EINTR(read(fd, data, size));
++  if (int ret = HANDLE_EINTR(close(fd)) < 0)
++    return ret;
++  return bytes_read;
+ }
+ 
+ int WriteFile(const FilePath& filename, const char* data, int size) {
+@@ -480,20 +523,24 @@ int WriteFile(const FilePath& filename, const char* data, int size) {
+   if (fd < 0)
+     return -1;
+ 
+-  // Allow for partial writes
++  int bytes_written = WriteFileDescriptor(fd, data, size);
++  if (int ret = HANDLE_EINTR(close(fd)) < 0)
++    return ret;
++  return bytes_written;
++}
++
++int WriteFileDescriptor(const int fd, const char* data, int size) {
++  // Allow for partial writes.
+   ssize_t bytes_written_total = 0;
+-  do {
+-    ssize_t bytes_written_partial =
+-      HANDLE_EINTR(write(fd, data + bytes_written_total,
+-                         size - bytes_written_total));
+-    if (bytes_written_partial < 0) {
+-      HANDLE_EINTR(close(fd));
++  for (ssize_t bytes_written_partial = 0; bytes_written_total < size;
++       bytes_written_total += bytes_written_partial) {
++    bytes_written_partial =
++        HANDLE_EINTR(write(fd, data + bytes_written_total,
++                           size - bytes_written_total));
++    if (bytes_written_partial < 0)
+       return -1;
+-    }
+-    bytes_written_total += bytes_written_partial;
+-  } while (bytes_written_total < size);
++  }
+ 
+-  HANDLE_EINTR(close(fd));
+   return bytes_written_total;
+ }
+ 
+@@ -520,10 +567,13 @@ bool SetCurrentDirectory(const FilePath& path) {
+ FileEnumerator::FileEnumerator(const FilePath& root_path,
+                                bool recursive,
+                                FileEnumerator::FILE_TYPE file_type)
+-    : recursive_(recursive),
++    : current_directory_entry_(0),
++      root_path_(root_path),
++      recursive_(recursive),
+       file_type_(file_type),
+-      is_in_find_op_(false),
+-      fts_(NULL) {
++      is_in_find_op_(false) {
++  // INCLUDE_DOT_DOT must not be specified if recursive.
++  DCHECK(!(recursive && (INCLUDE_DOT_DOT & file_type_)));
+   pending_paths_.push(root_path);
+ }
+ 
+@@ -531,136 +581,256 @@ FileEnumerator::FileEnumerator(const FilePath& root_path,
+                                bool recursive,
+                                FileEnumerator::FILE_TYPE file_type,
+                                const FilePath::StringType& pattern)
+-    : recursive_(recursive),
++    : current_directory_entry_(0),
++      root_path_(root_path),
++      recursive_(recursive),
+       file_type_(file_type),
+-      pattern_(root_path.value()),
+-      is_in_find_op_(false),
+-      fts_(NULL) {
+-  // The Windows version of this code only matches against items in the top-most
+-  // directory, and we're comparing fnmatch against full paths, so this is the
+-  // easiest way to get the right pattern.
+-  pattern_ = pattern_.Append(pattern);
++      pattern_(root_path.Append(pattern).value()),
++      is_in_find_op_(false) {
++  // INCLUDE_DOT_DOT must not be specified if recursive.
++  DCHECK(!(recursive && (INCLUDE_DOT_DOT & file_type_)));
++  // The Windows version of this code appends the pattern to the root_path,
++  // potentially only matching against items in the top-most directory.
++  // Do the same here.
++  if (pattern.size() == 0)
++    pattern_ = FilePath::StringType();
+   pending_paths_.push(root_path);
+ }
+ 
+ FileEnumerator::~FileEnumerator() {
+-#ifndef ANDROID
+-  if (fts_)
+-    fts_close(fts_);
+-#endif
+ }
+ 
+ void FileEnumerator::GetFindInfo(FindInfo* info) {
+   DCHECK(info);
+ 
+-  if (!is_in_find_op_)
++  if (current_directory_entry_ >= directory_entries_.size())
+     return;
+ 
+-#ifndef ANDROID
+-  memcpy(&(info->stat), fts_ent_->fts_statp, sizeof(info->stat));
+-  info->filename.assign(fts_ent_->fts_name);
+-#endif
++  DirectoryEntryInfo* cur_entry = &directory_entries_[current_directory_entry_];
++  memcpy(&(info->stat), &(cur_entry->stat), sizeof(info->stat));
++  info->filename.assign(cur_entry->filename.value());
++}
++
++bool FileEnumerator::IsDirectory(const FindInfo& info) {
++  return S_ISDIR(info.stat.st_mode);
++}
++
++// static
++FilePath FileEnumerator::GetFilename(const FindInfo& find_info) {
++  return FilePath(find_info.filename);
+ }
+ 
+-// As it stands, this method calls itself recursively when the next item of
+-// the fts enumeration doesn't match (type, pattern, etc.).  In the case of
+-// large directories with many files this can be quite deep.
+-// TODO(erikkay) - get rid of this recursive pattern
+ FilePath FileEnumerator::Next() {
+-#ifdef ANDROID
+-  return FilePath();
+-#else
+-  if (!is_in_find_op_) {
++  ++current_directory_entry_;
++
++  // While we've exhausted the entries in the current directory, do the next
++  while (current_directory_entry_ >= directory_entries_.size()) {
+     if (pending_paths_.empty())
+       return FilePath();
+ 
+-    // The last find FindFirstFile operation is done, prepare a new one.
+     root_path_ = pending_paths_.top();
+     root_path_ = root_path_.StripTrailingSeparators();
+     pending_paths_.pop();
+ 
+-    // Start a new find operation.
+-    int ftsflags = FTS_LOGICAL;
+-    char top_dir[PATH_MAX];
+-    base::strlcpy(top_dir, root_path_.value().c_str(), arraysize(top_dir));
+-    char* dir_list[2] = { top_dir, NULL };
+-    fts_ = fts_open(dir_list, ftsflags, NULL);
+-    if (!fts_)
+-      return Next();
+-    is_in_find_op_ = true;
+-  }
++    std::vector<DirectoryEntryInfo> entries;
++    if (!ReadDirectory(&entries, root_path_, file_type_ & SHOW_SYM_LINKS))
++      continue;
+ 
+-  fts_ent_ = fts_read(fts_);
+-  if (fts_ent_ == NULL) {
+-    fts_close(fts_);
+-    fts_ = NULL;
+-    is_in_find_op_ = false;
+-    return Next();
+-  }
++    directory_entries_.clear();
++    current_directory_entry_ = 0;
++    for (std::vector<DirectoryEntryInfo>::const_iterator
++        i = entries.begin(); i != entries.end(); ++i) {
++      FilePath full_path = root_path_.Append(i->filename);
++      if (ShouldSkip(full_path))
++        continue;
++
++      if (pattern_.size() &&
++          fnmatch(pattern_.c_str(), full_path.value().c_str(), FNM_NOESCAPE))
++        continue;
++
++      if (recursive_ && S_ISDIR(i->stat.st_mode))
++        pending_paths_.push(full_path);
+ 
+-  // Level 0 is the top, which is always skipped.
+-  if (fts_ent_->fts_level == 0)
+-    return Next();
+-
+-  // Patterns are only matched on the items in the top-most directory.
+-  // (see Windows implementation)
+-  if (fts_ent_->fts_level == 1 && pattern_.value().length() > 0) {
+-    if (fnmatch(pattern_.value().c_str(), fts_ent_->fts_path, 0) != 0) {
+-      if (fts_ent_->fts_info == FTS_D)
+-        fts_set(fts_, fts_ent_, FTS_SKIP);
+-      return Next();
++      if ((S_ISDIR(i->stat.st_mode) && (file_type_ & DIRECTORIES)) ||
++          (!S_ISDIR(i->stat.st_mode) && (file_type_ & FILES)))
++        directory_entries_.push_back(*i);
+     }
+   }
+ 
+-  FilePath cur_file(fts_ent_->fts_path);
+-  if (fts_ent_->fts_info == FTS_D) {
+-    // If not recursive, then prune children.
+-    if (!recursive_)
+-      fts_set(fts_, fts_ent_, FTS_SKIP);
+-    return (file_type_ & FileEnumerator::DIRECTORIES) ? cur_file : Next();
+-  } else if (fts_ent_->fts_info == FTS_F) {
+-    return (file_type_ & FileEnumerator::FILES) ? cur_file : Next();
+-  }
+-  // TODO(erikkay) - verify that the other fts_info types aren't interesting
+-  return Next();
++  return root_path_.Append(directory_entries_[current_directory_entry_
++      ].filename);
++}
++
++bool FileEnumerator::ReadDirectory(std::vector<DirectoryEntryInfo>* entries,
++                                   const FilePath& source, bool show_links) {
++
++  DIR* dir = opendir(source.value().c_str());
++  if (!dir)
++    return false;
++#ifdef OS_SOLARIS    
++  struct {
++          dirent dent_buffer;
++          char chars[MAXNAMLEN];
++  } dent_buf;
++#else  
++  struct dirent dent_buf;
++#endif  
++  struct dirent* dent;
++
++#if !defined(OS_LINUX) && !defined(OS_MACOSX) && !defined(OS_FREEBSD) && \
++    !defined(OS_OPENBSD) && !defined(OS_SOLARIS)
++  #error Port warning: depending on the definition of struct dirent, \
++         additional space for pathname may be needed
+ #endif
++
++  while (readdir_r(dir, (dirent *)&dent_buf, &dent) == 0 && dent) {
++    DirectoryEntryInfo info;
++    info.filename = FilePath(dent->d_name);
++
++    FilePath full_name = source.Append(dent->d_name);
++    int ret;
++    if (show_links)
++      ret = lstat(full_name.value().c_str(), &info.stat);
++    else
++      ret = stat(full_name.value().c_str(), &info.stat);
++    if (ret < 0) {
++      // Print the stat() error message unless it was ENOENT and we're
++      // following symlinks.
++      if (!(errno == ENOENT && !show_links)) {
++        LOG(ERROR) << "Couldn't stat "
++                   << source.Append(dent->d_name).value();
++      }
++      memset(&info.stat, 0, sizeof(info.stat));
++    }
++    entries->push_back(info);
++  }
++
++  closedir(dir);
++  return true;
+ }
+ 
+ ///////////////////////////////////////////////
+ // MemoryMappedFile
+ 
+ MemoryMappedFile::MemoryMappedFile()
+-    : file_(-1),
++    : file_(base::kInvalidPlatformFileValue),
+       data_(NULL),
+       length_(0) {
+ }
+ 
+-bool MemoryMappedFile::MapFileToMemory(const FilePath& file_name) {
+-  file_ = open(file_name.value().c_str(), O_RDONLY);
+-  if (file_ == -1)
+-    return false;
+-
++bool MemoryMappedFile::MapFileToMemoryInternal() {
+   struct stat file_stat;
+-  if (fstat(file_, &file_stat) == -1)
++  if (fstat(file_, &file_stat) == base::kInvalidPlatformFileValue) {
++    LOG(ERROR) << "Couldn't fstat " << file_ << ", errno " << errno;
+     return false;
++  }
+   length_ = file_stat.st_size;
+ 
+   data_ = static_cast<uint8*>(
+-      mmap(NULL, length_, PROT_READ, MAP_SHARED, file_, 0));
++      (void*)mmap(NULL, length_, PROT_READ, MAP_SHARED, file_, 0));
+   if (data_ == MAP_FAILED)
+-    data_ = NULL;
+-  return data_ != NULL;
++    LOG(ERROR) << "Couldn't mmap " << file_ << ", errno " << errno;
++
++  return data_ != MAP_FAILED;
+ }
+ 
+ void MemoryMappedFile::CloseHandles() {
+   if (data_ != NULL)
+-    munmap(data_, length_);
+-  if (file_ != -1)
++    munmap((caddr_t)data_, length_);
++  if (file_ != base::kInvalidPlatformFileValue)
+     close(file_);
+ 
+   data_ = NULL;
+   length_ = 0;
+-  file_ = -1;
++  file_ = base::kInvalidPlatformFileValue;
++}
++
++bool HasFileBeenModifiedSince(const FileEnumerator::FindInfo& find_info,
++                              const base::Time& cutoff_time) {
++  return find_info.stat.st_mtime >= cutoff_time.ToTimeT();
++}
++
++#if !defined(OS_MACOSX)
++bool GetTempDir(FilePath* path) {
++  const char* tmp = getenv("TMPDIR");
++  if (tmp)
++    *path = FilePath(tmp);
++  else
++    *path = FilePath("/tmp");
++  return true;
++}
++
++bool GetShmemTempDir(FilePath* path) {
++#ifdef OS_SOLARIS
++  *path = FilePath("/var/tmp");
++#else  
++  *path = FilePath("/dev/shm");
++#endif  
++  return true;
++}
++
++FilePath GetHomeDir() {
++  const char* home_dir = getenv("HOME");
++  if (home_dir && home_dir[0])
++    return FilePath(home_dir);
++
++  home_dir = g_get_home_dir();
++  if (home_dir && home_dir[0])
++    return FilePath(home_dir);
++
++  FilePath rv;
++  if (file_util::GetTempDir(&rv))
++    return rv;
++
++  // Last resort.
++  return FilePath("/tmp");
++}
++
++bool CopyFile(const FilePath& from_path, const FilePath& to_path) {
++  int infile = open(from_path.value().c_str(), O_RDONLY);
++  if (infile < 0)
++    return false;
++
++  int outfile = creat(to_path.value().c_str(), 0666);
++  if (outfile < 0) {
++    close(infile);
++    return false;
++  }
++
++  const size_t kBufferSize = 32768;
++  std::vector<char> buffer(kBufferSize);
++  bool result = true;
++
++  while (result) {
++    ssize_t bytes_read = HANDLE_EINTR(read(infile, &buffer[0], buffer.size()));
++    if (bytes_read < 0) {
++      result = false;
++      break;
++    }
++    if (bytes_read == 0)
++      break;
++    // Allow for partial writes
++    ssize_t bytes_written_per_read = 0;
++    do {
++      ssize_t bytes_written_partial = HANDLE_EINTR(write(
++          outfile,
++          &buffer[bytes_written_per_read],
++          bytes_read - bytes_written_per_read));
++      if (bytes_written_partial < 0) {
++        result = false;
++        break;
++      }
++      bytes_written_per_read += bytes_written_partial;
++    } while (bytes_written_per_read < bytes_read);
++  }
++
++  if (HANDLE_EINTR(close(infile)) < 0)
++    result = false;
++  if (HANDLE_EINTR(close(outfile)) < 0)
++    result = false;
++
++  return result;
+ }
++#endif  // defined(OS_MACOSX)
+ 
+ } // namespace file_util
+diff --git a/ipc/chromium/src/base/file_version_info.h b/ipc/chromium/src/base/file_version_info.h
+index f38d23f..065e9ac 100644
+--- a/ipc/chromium/src/base/file_version_info.h
++++ b/ipc/chromium/src/base/file_version_info.h
+@@ -86,7 +86,7 @@ class FileVersionInfo {
+   explicit FileVersionInfo(NSBundle *bundle);
+ 
+   NSBundle *bundle_;
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+   FileVersionInfo();
+ #endif
+ 
+diff --git a/ipc/chromium/src/base/float_util.h b/ipc/chromium/src/base/float_util.h
+index 5909995..905080b 100644
+--- a/ipc/chromium/src/base/float_util.h
++++ b/ipc/chromium/src/base/float_util.h
+@@ -8,6 +8,9 @@
+ #include "build/build_config.h"
+ 
+ #include <float.h>
++#ifdef OS_SOLARIS
++#include <ieeefp.h>
++#endif 
+ #include <math.h>
+ 
+ namespace base {
+diff --git a/ipc/chromium/src/base/gfx/native_widget_types.h b/ipc/chromium/src/base/gfx/native_widget_types.h
+index d43db5c..2f4ab87 100644
+--- a/ipc/chromium/src/base/gfx/native_widget_types.h
++++ b/ipc/chromium/src/base/gfx/native_widget_types.h
+@@ -46,7 +46,7 @@ class NSView;
+ class NSWindow;
+ class NSTextField;
+ #endif  // __OBJC__
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+ typedef struct _GtkWidget GtkWidget;
+ typedef struct _GtkWindow GtkWindow;
+ typedef struct _cairo_surface cairo_surface_t;
+@@ -64,7 +64,7 @@ typedef NSView* NativeView;
+ typedef NSWindow* NativeWindow;
+ typedef NSTextField* NativeEditView;
+ typedef CGContext* NativeDrawingContext;
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+ typedef GtkWidget* NativeView;
+ typedef GtkWindow* NativeWindow;
+ typedef GtkWidget* NativeEditView;
+@@ -86,7 +86,7 @@ typedef intptr_t NativeViewId;
+ static inline NativeView NativeViewFromId(NativeViewId id) {
+   return reinterpret_cast<NativeView>(id);
+ }
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+ // A NativeView on Linux is a GtkWidget*. However, we can't go directly from an
+ // X window ID to a GtkWidget. Thus, functions which handle NativeViewIds from
+ // the renderer have to use Xlib. This is fine since these functions are
+@@ -94,7 +94,7 @@ static inline NativeView NativeViewFromId(NativeViewId id) {
+ 
+ #define NativeViewFromId(x) NATIVE_VIEW_FROM_ID_NOT_AVAILIBLE_ON_LINUX
+ 
+-#endif  // defined(OS_LINUX)
++#endif  // defined(OS_LINUX) || defined(OS_SOLARIS)
+ 
+ // Convert a NativeView to a NativeViewId. See the comments above
+ // NativeViewFromId.
+@@ -102,10 +102,10 @@ static inline NativeView NativeViewFromId(NativeViewId id) {
+ static inline NativeViewId IdFromNativeView(NativeView view) {
+   return reinterpret_cast<NativeViewId>(view);
+ }
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+ // Not inlined because it involves pulling too many headers.
+ NativeViewId IdFromNativeView(NativeView view);
+-#endif  // defined(OS_LINUX)
++#endif  // defined(OS_LINUX) || defined(OS_SOLARIS)
+ 
+ }  // namespace gfx
+ 
+diff --git a/ipc/chromium/src/base/gfx/rect.cc b/ipc/chromium/src/base/gfx/rect.cc
+index e0226f3..3c89c2c 100755
+--- a/ipc/chromium/src/base/gfx/rect.cc
++++ b/ipc/chromium/src/base/gfx/rect.cc
+@@ -8,7 +8,7 @@
+ #include <windows.h>
+ #elif defined(OS_MACOSX)
+ #include <CoreGraphics/CGGeometry.h>
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+ #include <gdk/gdk.h>
+ #endif
+ 
+@@ -74,7 +74,7 @@ Rect& Rect::operator=(const CGRect& r) {
+   set_height(r.size.height);
+   return *this;
+ }
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+ Rect::Rect(const GdkRectangle& r)
+     : origin_(r.x, r.y) {
+   set_width(r.width);
+@@ -126,7 +126,7 @@ RECT Rect::ToRECT() const {
+   r.bottom = bottom();
+   return r;
+ }
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+ GdkRectangle Rect::ToGdkRectangle() const {
+   GdkRectangle r = {x(), y(), width(), height()};
+   return r;
+diff --git a/ipc/chromium/src/base/gfx/rect.h b/ipc/chromium/src/base/gfx/rect.h
+index 6da1b55..e866398 100644
+--- a/ipc/chromium/src/base/gfx/rect.h
++++ b/ipc/chromium/src/base/gfx/rect.h
+@@ -19,7 +19,7 @@
+ 
+ #if defined(OS_WIN)
+ typedef struct tagRECT RECT;
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+ typedef struct _GdkRectangle GdkRectangle;
+ #endif
+ 
+@@ -34,7 +34,7 @@ class Rect {
+   explicit Rect(const RECT& r);
+ #elif defined(OS_MACOSX)
+   explicit Rect(const CGRect& r);
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOALRIS)
+   explicit Rect(const GdkRectangle& r);
+ #endif
+   Rect(const gfx::Point& origin, const gfx::Size& size);
+@@ -45,7 +45,7 @@ class Rect {
+   Rect& operator=(const RECT& r);
+ #elif defined(OS_MACOSX)
+   Rect& operator=(const CGRect& r);
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+   Rect& operator=(const GdkRectangle& r);
+ #endif
+ 
+@@ -97,7 +97,7 @@ class Rect {
+ #if defined(OS_WIN)
+   // Construct an equivalent Win32 RECT object.
+   RECT ToRECT() const;
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+   GdkRectangle ToGdkRectangle() const;
+ #elif defined(OS_MACOSX)
+   // Construct an equivalent CoreGraphics object.
+diff --git a/ipc/chromium/src/base/hash_tables.h b/ipc/chromium/src/base/hash_tables.h
+index c2dcde5..1edd667 100644
+--- a/ipc/chromium/src/base/hash_tables.h
++++ b/ipc/chromium/src/base/hash_tables.h
+@@ -26,6 +26,15 @@ namespace base {
+ using stdext::hash_map;
+ using stdext::hash_set;
+ }
++#elif defined(COMPILER_SUNPRO)
++#include <map>
++#include <set>
++namespace base {
++using std::map;
++using std::set;
++}
++#define hash_map map
++#define hash_set set
+ #elif defined(COMPILER_GCC)
+ // This is a hack to disable the gcc 4.4 warning about hash_map and hash_set
+ // being deprecated.  We can get rid of this when we upgrade to VS2008 and we
+diff --git a/ipc/chromium/src/base/icu_util.cc b/ipc/chromium/src/base/icu_util.cc
+index 701dc73..1732c74 100644
+--- a/ipc/chromium/src/base/icu_util.cc
++++ b/ipc/chromium/src/base/icu_util.cc
+@@ -30,7 +30,7 @@
+ #define ICU_UTIL_DATA_IMPL ICU_UTIL_DATA_SHARED
+ #elif defined(OS_MACOSX)
+ #define ICU_UTIL_DATA_IMPL ICU_UTIL_DATA_STATIC
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+ #define ICU_UTIL_DATA_IMPL ICU_UTIL_DATA_FILE
+ #endif
+ 
+diff --git a/ipc/chromium/src/base/idle_timer.cc b/ipc/chromium/src/base/idle_timer.cc
+index de980f1..34ee461 100644
+--- a/ipc/chromium/src/base/idle_timer.cc
++++ b/ipc/chromium/src/base/idle_timer.cc
+@@ -7,13 +7,13 @@
+ // We may not want to port idle_timer to Linux, but we have implemented it
+ // anyway.  Define this to 1 to enable the Linux idle timer and then add the
+ // libs that need to be linked (Xss).
+-#define ENABLE_XSS_SUPPORT 0
++#define ENABLE_XSS_SUPPORT 1
+ 
+ #if defined(OS_MACOSX)
+ #include <ApplicationServices/ApplicationServices.h>
+ #endif
+ 
+-#if defined(OS_LINUX) && ENABLE_XSS_SUPPORT
++#if (defined(OS_LINUX) || defined(OS_SOLARIS)) && ENABLE_XSS_SUPPORT
+ // We may not want to port idle_timer to Linux, but we have implemented it
+ // anyway.  Remove the 0 above if we want it.
+ #include <gdk/gdkx.h>
+@@ -54,7 +54,7 @@ bool OSIdleTimeSource(int32 *milliseconds_interval_since_last_event) {
+           kCGAnyInputEventType) * 1000.0;
+   return true;
+ }
+-#elif defined(OS_LINUX) && ENABLE_XSS_SUPPORT
++#elif (defined(OS_LINUX) || defined(OS_SOLARIS)) && ENABLE_XSS_SUPPORT
+ class IdleState {
+  public:
+   IdleState() {
+diff --git a/ipc/chromium/src/base/logging.cc b/ipc/chromium/src/base/logging.cc
+index 33d4ca4..6fbb1e0 100644
+--- a/ipc/chromium/src/base/logging.cc
++++ b/ipc/chromium/src/base/logging.cc
+@@ -118,7 +118,7 @@ typedef HANDLE MutexHandle;
+ #include <mach/mach.h>
+ #include <mach/mach_time.h>
+ #include <mach-o/dyld.h>
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+ #include <sys/syscall.h>
+ #include <time.h>
+ #endif
+@@ -230,6 +230,8 @@ int32 CurrentThreadId() {
+   return mach_thread_self();
+ #elif defined(OS_LINUX)
+   return syscall(__NR_gettid);
++#elif defined(OS_SOLARIS)
++  return thr_self();
+ #endif
+ }
+ 
+@@ -238,7 +240,7 @@ uint64 TickCount() {
+   return GetTickCount();
+ #elif defined(OS_MACOSX)
+   return mach_absolute_time();
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+   struct timespec ts;
+   clock_gettime(CLOCK_MONOTONIC, &ts);
+ 
+diff --git a/ipc/chromium/src/base/message_loop.cc b/ipc/chromium/src/base/message_loop.cc
+index 6e62692..66b96ae 100644
+--- a/ipc/chromium/src/base/message_loop.cc
++++ b/ipc/chromium/src/base/message_loop.cc
+@@ -19,7 +19,7 @@
+ #if defined(OS_POSIX)
+ #include "base/message_pump_libevent.h"
+ #endif
+-#if defined(OS_LINUX)
++#if defined(OS_LINUX) || defined(OS_SOLARIS)
+ #ifdef MOZ_WIDGET_GTK2
+ #include "base/message_pump_glib.h"
+ #endif
+@@ -120,9 +120,9 @@ MessageLoop::MessageLoop(Type type)
+   if (type_ == TYPE_UI) {
+ #if defined(OS_MACOSX)
+     pump_ = base::MessagePumpMac::Create();
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+     pump_ = new base::MessagePumpForUI();
+-#endif  // OS_LINUX
++#endif  // OS_LINUX || OS_SOLARIS
+   } else if (type_ == TYPE_IO) {
+     pump_ = new base::MessagePumpLibevent();
+   } else {
+diff --git a/ipc/chromium/src/base/message_pump_glib.cc b/ipc/chromium/src/base/message_pump_glib.cc
+index 630c2f9..980bccd 100644
+--- a/ipc/chromium/src/base/message_pump_glib.cc
++++ b/ipc/chromium/src/base/message_pump_glib.cc
+@@ -126,16 +126,22 @@ namespace base {
+ 
+ MessagePumpForUI::MessagePumpForUI()
+     : state_(NULL),
+       context_(g_main_context_default()),
+       wakeup_gpollfd_(new GPollFD) {
+   // Create our wakeup pipe, which is used to flag when work was scheduled.
+   int fds[2];
+   CHECK(pipe(fds) == 0);
++
++  int flags = fcntl(fds[0], F_GETFL, 0);
++  if (flags == -1)
++    flags = 0;
++  fcntl(fds[0], F_SETFL, flags | O_NDELAY);
++
+   wakeup_pipe_read_  = fds[0];
+   wakeup_pipe_write_ = fds[1];
+   wakeup_gpollfd_->fd = wakeup_pipe_read_;
+   wakeup_gpollfd_->events = G_IO_IN;
+ 
+   work_source_ = g_source_new(&WorkSourceFuncs, sizeof(WorkSource));
+   static_cast<WorkSource*>(work_source_)->pump = this;
+   g_source_add_poll(work_source_, wakeup_gpollfd_.get());
+@@ -232,20 +238,19 @@ int MessagePumpForUI::HandlePrepare() {
+ bool MessagePumpForUI::HandleCheck() {
+   if (!state_)  // state_ may be null during tests.
+     return false;
+ 
+   // We should only ever have a single message on the wakeup pipe, since we
+   // are only signaled when the queue went from empty to non-empty.  The glib
+   // poll will tell us whether there was data, so this read shouldn't block.
+   if (wakeup_gpollfd_->revents & G_IO_IN) {
+-    char msg;
+-    if (HANDLE_EINTR(read(wakeup_pipe_read_, &msg, 1)) != 1 || msg != '!') {
+-      NOTREACHED() << "Error reading from the wakeup pipe.";
+-    }
++    char buf[32];
++    while (HANDLE_EINTR(read(wakeup_pipe_read_, &buf, 32)));
++
+     // Since we ate the message, we need to record that we have more work,
+     // because HandleCheck() may be called without HandleDispatch being called
+     // afterwards.
+     state_->has_work = true;
+   }
+ 
+   if (state_->has_work)
+     return true;
+@@ -299,16 +304,20 @@ void MessagePumpForUI::Quit() {
+   }
+ }
+ 
+ void MessagePumpForUI::ScheduleWork() {
+   // This can be called on any thread, so we don't want to touch any state
+   // variables as we would then need locks all over.  This ensures that if
+   // we are sleeping in a poll that we will wake up.
+   char msg = '!';
++
++  char buf[32];
++  while (HANDLE_EINTR(read(wakeup_pipe_read_, &buf, 32)));
++
+   if (HANDLE_EINTR(write(wakeup_pipe_write_, &msg, 1)) != 1) {
+     NOTREACHED() << "Could not write to the UI message loop wakeup pipe!";
+   }
+ }
+ 
+ void MessagePumpForUI::ScheduleDelayedWork(const Time& delayed_work_time) {
+   // We need to wake up the loop in case the poll timeout needs to be
+   // adjusted.  This will cause us to try to do work, but that's ok.
+diff --git a/ipc/chromium/src/base/message_pump_libevent.cc b/ipc/chromium/src/base/message_pump_libevent.cc
+index b537988..16ec112 100644
+--- a/ipc/chromium/src/base/message_pump_libevent.cc
++++ b/ipc/chromium/src/base/message_pump_libevent.cc
+@@ -6,6 +6,10 @@
+ 
+ #include <errno.h>
+ #include <fcntl.h>
++#if defined(OS_SOLARIS)
++#include <unistd.h>
++#include <sys/stat.h>
++#endif
+ 
+ #include "eintr_wrapper.h"
+ #include "base/logging.h"
+diff --git a/ipc/chromium/src/base/native_library.h b/ipc/chromium/src/base/native_library.h
+index ce85c23..81d54a1 100644
+--- a/ipc/chromium/src/base/native_library.h
++++ b/ipc/chromium/src/base/native_library.h
+@@ -26,7 +26,7 @@ typedef char* NativeLibraryFunctionNameType;
+ #elif defined(OS_MACOSX)
+ typedef CFBundleRef NativeLibrary;
+ typedef CFStringRef NativeLibraryFunctionNameType;
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+ typedef void* NativeLibrary;
+ typedef const char* NativeLibraryFunctionNameType;
+ #endif  // OS_*
+diff --git a/ipc/chromium/src/base/observer_list.h b/ipc/chromium/src/base/observer_list.h
+index f67df14..3f26f93 100644
+--- a/ipc/chromium/src/base/observer_list.h
++++ b/ipc/chromium/src/base/observer_list.h
+@@ -82,7 +82,7 @@ class ObserverList {
+ 
+   // Add an observer to the list.
+   void AddObserver(ObserverType* obs) {
+-    DCHECK(find(observers_.begin(), observers_.end(), obs) == observers_.end())
++    DCHECK(std::find(observers_.begin(), observers_.end(), obs) == observers_.end())
+         << "Observers can only be added once!";
+     observers_.push_back(obs);
+   }
+diff --git a/ipc/chromium/src/base/path_service.cc b/ipc/chromium/src/base/path_service.cc
+index f625c98..3228de7 100644
+--- a/ipc/chromium/src/base/path_service.cc
++++ b/ipc/chromium/src/base/path_service.cc
+@@ -24,7 +24,7 @@ namespace base {
+   bool PathProviderWin(int key, FilePath* result);
+ #elif defined(OS_MACOSX)
+   bool PathProviderMac(int key, FilePath* result);
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+   bool PathProviderLinux(int key, FilePath* result);
+ #endif
+ }
+@@ -80,7 +80,7 @@ static Provider base_provider_mac = {
+ };
+ #endif
+ 
+-#if defined(OS_LINUX)
++#if defined(OS_LINUX) || defined(OS_SOLARIS)
+ static Provider base_provider_linux = {
+   base::PathProviderLinux,
+   &base_provider,
+@@ -92,6 +92,17 @@ static Provider base_provider_linux = {
+ };
+ #endif
+ 
++#if 0//defined(OS_SOLARIS)
++static Provider base_provider_posix = {
++  base::PathProviderPosix,
++  &base_provider,
++#ifndef NDEBUG
++  0,
++  0,
++#endif
++  true
++};
++#endif
+ 
+ struct PathData {
+   Lock      lock;
+@@ -104,7 +115,7 @@ struct PathData {
+     providers = &base_provider_win;
+ #elif defined(OS_MACOSX)
+     providers = &base_provider_mac;
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+     providers = &base_provider_linux;
+ #endif
+   }
+@@ -206,6 +217,24 @@ bool PathService::IsOverridden(int key) {
+   return path_data->overrides.find(key) != path_data->overrides.end();
+ }
+ 
++#ifdef OS_SOLARIS
++bool PathService::Override(int key, const FilePath& path) {
++  PathData* path_data = GetPathData();
++  DCHECK(path_data);
++  DCHECK(key > base::DIR_CURRENT) << "invalid path key";
++
++  FilePath file_path = path;
++
++  // make sure the directory exists:
++  if (!file_util::CreateDirectory(file_path))
++    return false;
++
++  AutoLock scoped_lock(path_data->lock);
++  path_data->cache[key] = file_path;
++  path_data->overrides.insert(key);
++  return true;
++}
++#else
+ bool PathService::Override(int key, const std::wstring& path) {
+   PathData* path_data = GetPathData();
+   DCHECK(path_data);
+@@ -231,8 +260,13 @@ bool PathService::Override(int key, const std::wstring& path) {
+   path_data->overrides.insert(key);
+   return true;
+ }
++#endif
+ 
++#ifdef OS_SOLARIS
++bool PathService::SetCurrentDirectory(const FilePath& current_directory) {
++#else
+ bool PathService::SetCurrentDirectory(const std::wstring& current_directory) {
++#endif
+   return file_util::SetCurrentDirectory(current_directory);
+ }
+ 
+diff --git a/ipc/chromium/src/base/path_service.h b/ipc/chromium/src/base/path_service.h
+index 86d6a4a..41a7d56 100644
+--- a/ipc/chromium/src/base/path_service.h
++++ b/ipc/chromium/src/base/path_service.h
+@@ -48,13 +48,21 @@ class PathService {
+   //
+   // WARNING: Consumers of PathService::Get may expect paths to be constant
+   // over the lifetime of the app, so this method should be used with caution.
++#ifdef OS_SOLARIS  
++  static bool Override(int key, const FilePath& path);
++#else
+   static bool Override(int key, const std::wstring& path);
++#endif
+ 
+   // Return whether a path was overridden.
+   static bool IsOverridden(int key);
+ 
+   // Sets the current directory.
++#ifdef OS_SOLARIS  
++  static bool SetCurrentDirectory(const FilePath& current_directory);
++#else  
+   static bool SetCurrentDirectory(const std::wstring& current_directory);
++#endif
+ 
+   // To extend the set of supported keys, you can register a path provider,
+   // which is just a function mirroring PathService::Get.  The ProviderFunc
+diff --git a/ipc/chromium/src/base/pickle.cc b/ipc/chromium/src/base/pickle.cc
+index da42457..214caee 100644
+--- a/ipc/chromium/src/base/pickle.cc
++++ b/ipc/chromium/src/base/pickle.cc
+@@ -8,6 +8,7 @@
+ 
+ #include <limits>
+ #include <string>
++#include <algorithm>
+ 
+ //------------------------------------------------------------------------------
+ 
+@@ -102,29 +103,23 @@ bool Pickle::ReadBool(void** iter, bool* result) const {
+ 
+ bool Pickle::ReadInt16(void** iter, int16* result) const {
+   DCHECK(iter);
+-  if (!*iter)
+-    *iter = const_cast<char*>(payload());
+ 
+-  if (!IteratorHasRoomFor(*iter, sizeof(*result)))
++  int tmp;
++  if (!ReadInt(iter, &tmp))
+     return false;
+ 
+-  memcpy(result, *iter, sizeof(*result));
+-
+-  UpdateIter(iter, sizeof(*result));
++  *result = tmp;
+   return true;
+ }
+ 
+ bool Pickle::ReadUInt16(void** iter, uint16* result) const {
+   DCHECK(iter);
+-  if (!*iter)
+-    *iter = const_cast<char*>(payload());
+ 
+-  if (!IteratorHasRoomFor(*iter, sizeof(*result)))
++  int tmp;
++  if (!ReadInt(iter, &tmp))
+     return false;
+ 
+-  memcpy(result, *iter, sizeof(*result));
+-
+-  UpdateIter(iter, sizeof(*result));
++  *result = tmp;
+   return true;
+ }
+ 
+diff --git a/ipc/chromium/src/base/platform_file_posix.cc b/ipc/chromium/src/base/platform_file_posix.cc
+index 57cb6e3..5dad416 100644
+--- a/ipc/chromium/src/base/platform_file_posix.cc
++++ b/ipc/chromium/src/base/platform_file_posix.cc
+@@ -8,6 +8,8 @@
+ #include <errno.h>
+ #ifdef ANDROID
+ #include <linux/stat.h>
++#elif defined(OS_SOLARIS)
++#include <sys/stat.h>
+ #endif
+ 
+ #include "base/logging.h"
+diff --git a/ipc/chromium/src/base/platform_thread.h b/ipc/chromium/src/base/platform_thread.h
+index 4a2d507..8a124f6 100644
+--- a/ipc/chromium/src/base/platform_thread.h
++++ b/ipc/chromium/src/base/platform_thread.h
+@@ -22,7 +22,7 @@ typedef void* PlatformThreadHandle;  // HANDLE
+ #elif defined(OS_POSIX)
+ #include <pthread.h>
+ typedef pthread_t PlatformThreadHandle;
+-#if defined(OS_LINUX)
++#if defined(OS_LINUX) || defined(OS_SOLARIS)
+ #include <unistd.h>
+ typedef pid_t PlatformThreadId;
+ #elif defined(OS_MACOSX)
+diff --git a/ipc/chromium/src/base/platform_thread_posix.cc b/ipc/chromium/src/base/platform_thread_posix.cc
+index 3789715..965055e 100644
+--- a/ipc/chromium/src/base/platform_thread_posix.cc
++++ b/ipc/chromium/src/base/platform_thread_posix.cc
+@@ -9,10 +9,13 @@
+ 
+ #if defined(OS_MACOSX)
+ #include <mach/mach.h>
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+ #include <sys/syscall.h>
+ #include <unistd.h>
+ #endif
++#if defined(OS_SOLARIS)
++#include <thread.h>
++#endif
+ 
+ #if defined(OS_MACOSX)
+ namespace base {
+@@ -35,6 +38,8 @@ PlatformThreadId PlatformThread::CurrentId() {
+   return mach_thread_self();
+ #elif defined(OS_LINUX)
+   return syscall(__NR_gettid);
++#elif defined(OS_SOLARIS)
++  return thr_self();
+ #endif
+ }
+ 
+diff --git a/ipc/chromium/src/base/port.h b/ipc/chromium/src/base/port.h
+index 0fc530d..2609c3e 100644
+--- a/ipc/chromium/src/base/port.h
++++ b/ipc/chromium/src/base/port.h
+@@ -44,7 +44,7 @@ namespace base {
+ inline void va_copy(va_list& a, va_list& b) {
+ #if defined(COMPILER_GCC)
+   ::va_copy(a, b);
+-#elif defined(COMPILER_MSVC)
++#elif defined(COMPILER_MSVC) || defined(COMPILER_SUNPRO)
+   a = b;
+ #endif
+ }
+@@ -54,7 +54,7 @@ inline void va_copy(va_list& a, va_list& b) {
+ // use va_list as ref args to a function, as above, breaks some machines.
+ #  if defined(COMPILER_GCC)
+ #    define base_va_copy(_a, _b) ::va_copy(_a, _b)
+-#  elif defined(COMPILER_MSVC)
++#  elif defined(COMPILER_MSVC) || defined(COMPILER_SUNPRO)
+ #    define base_va_copy(_a, _b) (_a = _b)
+ #  else
+ #    error No va_copy for your compiler
+@@ -67,7 +67,7 @@ inline void va_copy(va_list& a, va_list& b) {
+ // Define an OS-neutral wrapper for shared library entry points
+ #if defined(OS_WIN)
+ #define API_CALL __stdcall
+-#elif defined(OS_LINUX) || defined(OS_MACOSX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS) || defined(OS_MACOSX)
+ #define API_CALL
+ #endif
+ 
+diff --git a/ipc/chromium/src/base/process_util.h b/ipc/chromium/src/base/process_util.h
+index 914a34b..e3527d3 100644
+--- a/ipc/chromium/src/base/process_util.h
++++ b/ipc/chromium/src/base/process_util.h
+@@ -13,7 +13,7 @@
+ #if defined(OS_WIN)
+ #include <windows.h>
+ #include <tlhelp32.h>
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+ #include <dirent.h>
+ #include <limits.h>
+ #include <sys/types.h>
+@@ -21,6 +21,10 @@
+ #include <mach/mach.h>
+ #endif
+ 
++#if defined(OS_SOLARIS)
++#define NAME_MAX 14
++#endif
++
+ #include <map>
+ #include <string>
+ #include <vector>
+@@ -62,7 +66,8 @@ enum ProcessArchitecture {
+   PROCESS_ARCH_I386 = 0x1,
+   PROCESS_ARCH_X86_64 = 0x2,
+   PROCESS_ARCH_PPC = 0x4,
+-  PROCESS_ARCH_ARM = 0x8
++  PROCESS_ARCH_ARM = 0x8,
++  PROCESS_ARCH_SPARC = 0x10
+ };
+ 
+ static ProcessArchitecture GetCurrentProcessArchitecture()
+@@ -76,6 +81,8 @@ static ProcessArchitecture GetCurrentProcessArchitecture()
+   currentArchitecture = base::PROCESS_ARCH_PPC;
+ #elif defined(ARCH_CPU_ARMEL)
+   currentArchitecture = base::PROCESS_ARCH_ARM;
++#elif defined(ARCH_CPU_SPARC)
++  currentArchitecture = base::PROCESS_ARCH_SPARC;
+ #endif
+   return currentArchitecture;
+ }
+@@ -296,7 +303,7 @@ class NamedProcessIterator {
+ #if defined(OS_WIN)
+   HANDLE snapshot_;
+   bool started_iteration_;
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+   DIR *procfs_dir_;
+ #elif defined(OS_MACOSX)
+   std::vector<kinfo_proc> kinfo_procs_;
+diff --git a/ipc/chromium/src/base/process_util_posix.cc b/ipc/chromium/src/base/process_util_posix.cc
+index 7d83431..1686121 100644
+--- a/ipc/chromium/src/base/process_util_posix.cc
++++ b/ipc/chromium/src/base/process_util_posix.cc
+@@ -102,7 +102,7 @@ typedef unsigned long int rlim_t;
+ #endif
+ 
+ void CloseSuperfluousFds(const base::InjectiveMultimap& saved_mapping) {
+-#if defined(OS_LINUX)
++#if defined(OS_LINUX) || defined(OS_SOLARIS)
+   static const rlim_t kSystemDefaultMaxFds = 8192;
+   static const char fd_dir[] = "/proc/self/fd";
+ #elif defined(OS_MACOSX)
+@@ -179,7 +179,7 @@ void CloseSuperfluousFds(const base::InjectiveMultimap& saved_mapping) {
+ // TODO(agl): Remove this function. It's fundamentally broken for multithreaded
+ // apps.
+ void SetAllFDsToCloseOnExec() {
+-#if defined(OS_LINUX)
++#if defined(OS_LINUX) || defined(OS_SOLARIS)
+   const char fd_dir[] = "/proc/self/fd";
+ #elif defined(OS_MACOSX)
+   const char fd_dir[] = "/dev/fd";
+diff --git a/ipc/chromium/src/base/shared_memory_posix.cc b/ipc/chromium/src/base/shared_memory_posix.cc
+index 3a26550..006672e 100644
+--- a/ipc/chromium/src/base/shared_memory_posix.cc
++++ b/ipc/chromium/src/base/shared_memory_posix.cc
+@@ -136,9 +136,15 @@ bool SharedMemory::FilenameForMemoryName(const std::wstring &memname,
+   if (file_util::GetShmemTempDir(&temp_dir) == false)
+     return false;
+ 
++#ifndef OS_SOLARIS    
+   mem_filename = UTF8ToWide(temp_dir.value());
+   file_util::AppendToPath(&mem_filename, L"com.google.chrome.shmem." + memname);
+   *filename = mem_filename;
++#else  
++  *filename = (temp_dir.Append("com.google.chrome.shmem." +
++                               WideToUTF8(memname))).ToWStringHack();
++#endif                               
++
+   return true;
+ }
+ 
+@@ -256,7 +262,7 @@ bool SharedMemory::Unmap() {
+   if (memory_ == NULL)
+     return false;
+ 
+-  munmap(memory_, max_size_);
++  munmap((caddr_t)memory_, max_size_);
+   memory_ = NULL;
+   max_size_ = 0;
+   return true;
+diff --git a/ipc/chromium/src/base/stack_container.h b/ipc/chromium/src/base/stack_container.h
+index 1b325b1..379a614 100644
+--- a/ipc/chromium/src/base/stack_container.h
++++ b/ipc/chromium/src/base/stack_container.h
+@@ -96,12 +96,17 @@ class StackAllocator : public std::allocator<T> {
+   // and the size requested fits. Otherwise, fall through to the standard
+   // allocator.
+   pointer allocate(size_type n, void* hint = 0) {
++#ifdef COMPILER_SUNPRO  
++    if (source_ != NULL && !source_->used_stack_buffer_
++        && (n/sizeof(T)) <= stack_capacity) {
++#else
+     if (source_ != NULL && !source_->used_stack_buffer_
+         && n <= stack_capacity) {
++#endif
+       source_->used_stack_buffer_ = true;
+       return source_->stack_buffer();
+     } else {
+-      return std::allocator<T>::allocate(n, hint);
++      return (pointer)std::allocator<T>::allocate(n, hint);
+     }
+   }
+ 
+diff --git a/ipc/chromium/src/base/string16.h b/ipc/chromium/src/base/string16.h
+index 28cf3d8..80d5e68 100644
+--- a/ipc/chromium/src/base/string16.h
++++ b/ipc/chromium/src/base/string16.h
+@@ -162,7 +162,9 @@ struct string16_char_traits {
+ //
+ // TODO(mark): File this bug with Apple and update this note with a bug number.
+ 
++#ifndef COMPILER_SUNPRO
+ extern template class std::basic_string<char16, base::string16_char_traits>;
++#endif
+ 
+ typedef std::basic_string<char16, base::string16_char_traits> string16;
+ 
+diff --git a/ipc/chromium/src/base/string_piece.h b/ipc/chromium/src/base/string_piece.h
+index fe10806..ae3106d 100644
+--- a/ipc/chromium/src/base/string_piece.h
++++ b/ipc/chromium/src/base/string_piece.h
+@@ -113,8 +113,13 @@ class StringPiece {
+   static const size_type npos;
+   typedef const char* const_iterator;
+   typedef const char* iterator;
++#ifdef COMPILER_SUNPRO
++  typedef std::reverse_iterator<const_iterator, std::random_access_iterator_tag, const value_type> const_reverse_iterator;
++  typedef std::reverse_iterator<iterator, std::random_access_iterator_tag, value_type> reverse_iterator;
++#else
+   typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+   typedef std::reverse_iterator<iterator> reverse_iterator;
++#endif
+   iterator begin() const { return ptr_; }
+   iterator end() const { return ptr_ + length_; }
+   const_reverse_iterator rbegin() const {
+diff --git a/ipc/chromium/src/base/string_util.cc b/ipc/chromium/src/base/string_util.cc
+index 1566ed6..991d8ea 100644
+--- a/ipc/chromium/src/base/string_util.cc
++++ b/ipc/chromium/src/base/string_util.cc
+@@ -503,22 +503,46 @@ std::wstring CollapseWhitespace(const std::wstring& text,
+ 
+ std::string WideToASCII(const std::wstring& wide) {
+   DCHECK(IsStringASCII(wide));
++#ifdef COMPILER_SUNPRO
++  std::string str(wide.length(), ' ');
++  std::copy(wide.begin(), wide.end(), str.begin());
++  return str;
++#else
+   return std::string(wide.begin(), wide.end());
++#endif
+ }
+ 
+ std::wstring ASCIIToWide(const std::string& ascii) {
+   DCHECK(IsStringASCII(ascii));
++#ifdef COMPILER_SUNPRO
++  std::wstring wstr(ascii.length(), L' ');
++  std::copy(ascii.begin(), ascii.end(), wstr.begin());
++  return wstr;
++#else
+   return std::wstring(ascii.begin(), ascii.end());
++#endif
+ }
+ 
+ std::string UTF16ToASCII(const string16& utf16) {
+   DCHECK(IsStringASCII(utf16));
++#ifdef COMPILER_SUNPRO
++  std::string str(utf16.length(), ' ');
++  std::copy(utf16.begin(), utf16.end(), str.begin());
++  return str;
++#else
+   return std::string(utf16.begin(), utf16.end());
++#endif
+ }
+ 
+ string16 ASCIIToUTF16(const std::string& ascii) {
+   DCHECK(IsStringASCII(ascii));
++#ifdef COMPILER_SUNPRO
++  string16 str(ascii.length(), ' ');
++  std::copy(ascii.begin(), ascii.end(), str.begin());
++  return str;
++#else
+   return string16(ascii.begin(), ascii.end());
++#endif
+ }
+ 
+ // Latin1 is just the low range of Unicode, so we can copy directly to convert.
+@@ -734,6 +758,7 @@ bool LowerCaseEqualsASCII(std::wstring::const_iterator a_begin,
+                           const char* b) {
+   return DoLowerCaseEqualsASCII(a_begin, a_end, b);
+ }
++#ifndef COMPILER_SUNPRO
+ bool LowerCaseEqualsASCII(const char* a_begin,
+                           const char* a_end,
+                           const char* b) {
+@@ -744,6 +769,7 @@ bool LowerCaseEqualsASCII(const wchar_t* a_begin,
+                           const char* b) {
+   return DoLowerCaseEqualsASCII(a_begin, a_end, b);
+ }
++#endif
+ 
+ bool StartsWithASCII(const std::string& str,
+                      const std::string& search,
+diff --git a/ipc/chromium/src/base/sys_info_posix.cc b/ipc/chromium/src/base/sys_info_posix.cc
+index 33ed0f7..b5bd350 100644
+--- a/ipc/chromium/src/base/sys_info_posix.cc
++++ b/ipc/chromium/src/base/sys_info_posix.cc
+@@ -96,7 +96,7 @@ std::wstring SysInfo::GetEnvVar(const wchar_t* var) {
+ 
+ // static
+ std::string SysInfo::OperatingSystemName() {
+-  utsname info;
++  struct utsname info;
+   if (uname(&info) < 0) {
+     NOTREACHED();
+     return "";
+@@ -106,7 +106,7 @@ std::string SysInfo::OperatingSystemName() {
+ 
+ // static
+ std::string SysInfo::OperatingSystemVersion() {
+-  utsname info;
++  struct utsname info;
+   if (uname(&info) < 0) {
+     NOTREACHED();
+     return "";
+@@ -116,7 +116,7 @@ std::string SysInfo::OperatingSystemVersion() {
+ 
+ // static
+ std::string SysInfo::CPUArchitecture() {
+-  utsname info;
++  struct utsname info;
+   if (uname(&info) < 0) {
+     NOTREACHED();
+     return "";
+diff --git a/ipc/chromium/src/base/third_party/nspr/prcpucfg.h b/ipc/chromium/src/base/third_party/nspr/prcpucfg.h
+index d54f0d1..a2726fa 100644
+--- a/ipc/chromium/src/base/third_party/nspr/prcpucfg.h
++++ b/ipc/chromium/src/base/third_party/nspr/prcpucfg.h
+@@ -36,6 +36,8 @@
+ #include "base/third_party/nspr/prcpucfg_mac.h"
+ #elif defined(__linux__) || defined(ANDROID)
+ #include "base/third_party/nspr/prcpucfg_linux.h"
++#elif defined(__sun) || defined(sun)
++#include "base/third_party/nspr/prcpucfg_solaris.h"
+ #else
+ #error Provide a prcpucfg.h appropriate for your platform
+ #endif
+diff --git a/ipc/chromium/src/base/third_party/nspr/prtime.cc b/ipc/chromium/src/base/third_party/nspr/prtime.cc
+index e6176aa..62473f7 100644
+--- a/ipc/chromium/src/base/third_party/nspr/prtime.cc
++++ b/ipc/chromium/src/base/third_party/nspr/prtime.cc
+@@ -242,6 +242,49 @@ PR_ImplodeTime(const PRExplodedTime *exploded)
+     result *= kSecondsToMicroseconds;
+     result += exploded->tm_usec;
+     return result;
++#elif defined(OS_SOLARIS)
++
++#define COUNT_LEAPS(Y)   ( ((Y)-1)/4 - ((Y)-1)/100 + ((Y)-1)/400 )
++#define COUNT_DAYS(Y)  ( ((Y)-1)*365 + COUNT_LEAPS(Y) )
++#define DAYS_BETWEEN_YEARS(A, B)  (COUNT_DAYS(B) - COUNT_DAYS(A))
++#define LL_ADD(r, a, b)     ((r) = (a) + (b))
++#define LL_SUB(r, a, b)     ((r) = (a) - (b))
++
++    PRExplodedTime copy;
++    PRTime retVal;
++    PRInt64 secPerDay, usecPerSec;
++    PRInt64 temp;
++    PRInt64 numSecs64;
++    PRInt32 numDays;
++    PRInt32 numSecs;
++
++    /* Normalize first.  Do this on our copy */
++    copy = *exploded;
++    PR_NormalizeTime(&copy, PR_GMTParameters);
++
++    numDays = DAYS_BETWEEN_YEARS(1970, copy.tm_year);
++    
++    numSecs = copy.tm_yday * 86400 + copy.tm_hour * 3600 
++            + copy.tm_min * 60 + copy.tm_sec;
++
++    LL_I2L(temp, numDays);
++    LL_I2L(secPerDay, 86400);
++    LL_MUL(temp, temp, secPerDay);
++    LL_I2L(numSecs64, numSecs);
++    LL_ADD(numSecs64, numSecs64, temp);
++
++    /* apply the GMT and DST offsets */
++    LL_I2L(temp,  copy.tm_params.tp_gmt_offset);
++    LL_SUB(numSecs64, numSecs64, temp);
++    LL_I2L(temp,  copy.tm_params.tp_dst_offset);
++    LL_SUB(numSecs64, numSecs64, temp);
++
++    LL_I2L(usecPerSec, 1000000L);
++    LL_MUL(temp, numSecs64, usecPerSec);
++    LL_I2L(retVal, copy.tm_usec);
++    LL_ADD(retVal, retVal, temp);
++
++    return retVal;
+ #else
+ #error No PR_ImplodeTime implemented on your platform.
+ #endif
+diff --git a/ipc/chromium/src/base/time.h b/ipc/chromium/src/base/time.h
+index 0625bfb..a62f20d 100644
+--- a/ipc/chromium/src/base/time.h
++++ b/ipc/chromium/src/base/time.h
+@@ -62,6 +62,10 @@ class TimeDelta {
+     return delta_;
+   }
+ 
++#if defined(OS_POSIX)
++  struct timespec ToTimeSpec() const;
++#endif
++
+   // Returns the time delta in some unit. The F versions return a floating
+   // point value, the "regular" versions return a rounded-down value.
+   int InDays() const;
+@@ -224,6 +228,10 @@ class Time {
+   static Time FromDoubleT(double dt);
+   double ToDoubleT() const;
+ 
++#if defined(OS_POSIX)
++  struct timeval ToTimeVal() const;
++#endif
++
+ 
+ #if defined(OS_WIN)
+   static Time FromFileTime(FILETIME ft);
+diff --git a/ipc/chromium/src/base/time_posix.cc b/ipc/chromium/src/base/time_posix.cc
+index 1014962..3bd0bad 100644
+--- a/ipc/chromium/src/base/time_posix.cc
++++ b/ipc/chromium/src/base/time_posix.cc
+@@ -62,11 +62,13 @@ Time Time::FromExploded(bool is_local, const Exploded& exploded) {
+   timestruct.tm_wday   = exploded.day_of_week;  // mktime/timegm ignore this
+   timestruct.tm_yday   = 0;     // mktime/timegm ignore this
+   timestruct.tm_isdst  = -1;    // attempt to figure it out
++#ifndef OS_SOLARIS
+   timestruct.tm_gmtoff = 0;     // not a POSIX field, so mktime/timegm ignore
+   timestruct.tm_zone   = NULL;  // not a POSIX field, so mktime/timegm ignore
+-
++#endif
++  
+   time_t seconds;
+-#ifdef ANDROID
++#if defined(ANDROID) || defined(OS_SOLARIS)
+     seconds = mktime(&timestruct);
+ #else
+   if (is_local)
+@@ -165,7 +167,7 @@ TimeTicks TimeTicks::Now() {
+   // reported in nanoseconds is enough to last nearly 585 years.
+ 
+ #elif defined(OS_POSIX) && \
+-      defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0
++      defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0 || defined(OS_SOLARIS)
+ 
+   struct timespec ts;
+   if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
+@@ -189,4 +191,25 @@ TimeTicks TimeTicks::HighResNow() {
+   return Now();
+ }
+ 
++struct timespec TimeDelta::ToTimeSpec() const {
++  int64 microseconds = InMicroseconds();
++  time_t seconds = 0;
++  if (microseconds >= Time::kMicrosecondsPerSecond) {
++    seconds = InSeconds();
++    microseconds -= seconds * Time::kMicrosecondsPerSecond;
++  }
++  struct timespec result =
++      {seconds,
++       microseconds * Time::kNanosecondsPerMicrosecond};
++  return result;
++}
++
++struct timeval Time::ToTimeVal() const {
++  struct timeval result;
++  int64 us = us_ - kTimeTToMicrosecondsOffset;
++  result.tv_sec = us / Time::kMicrosecondsPerSecond;
++  result.tv_usec = us % Time::kMicrosecondsPerSecond;
++  return result;
++}
++
+ }  // namespace base
+diff --git a/ipc/chromium/src/base/tracked_objects.cc b/ipc/chromium/src/base/tracked_objects.cc
+index 7506df7..63cd557 100644
+--- a/ipc/chromium/src/base/tracked_objects.cc
++++ b/ipc/chromium/src/base/tracked_objects.cc
+@@ -804,7 +804,11 @@ void Comparator::SetSubgroupTiebreaker(Selector selector) {
+ }
+ 
+ void Comparator::ParseKeyphrase(const std::string key_phrase) {
++#if defined(COMPILER_SUNPRO)
++  static std::map<std::string, Selector> key_map;
++#else
+   static std::map<const std::string, Selector> key_map;
++#endif
+   static bool initialized = false;
+   if (!initialized) {
+     initialized = true;
+diff --git a/ipc/chromium/src/build/build_config.h b/ipc/chromium/src/build/build_config.h
+index 06ee253..319cada 100644
+--- a/ipc/chromium/src/build/build_config.h
++++ b/ipc/chromium/src/build/build_config.h
+@@ -4,9 +4,9 @@
+ 
+ // This file adds defines about the platform we're currently building on.
+ //  Operating System:
+-//    OS_WIN / OS_MACOSX / OS_LINUX / OS_POSIX (MACOSX or LINUX)
++//    OS_WIN / OS_MACOSX / OS_LINUX / OS_SOLARIS / OS_POSIX (MACOSX or LINUX)
+ //  Compiler:
+-//    COMPILER_MSVC / COMPILER_GCC
++//    COMPILER_MSVC / COMPILER_GCC / COMPILER_SUNPRO
+ //  Processor:
+ //    ARCH_CPU_X86 / ARCH_CPU_X86_64 / ARCH_CPU_X86_FAMILY (X86 or X86_64)
+ //    ARCH_CPU_32_BITS / ARCH_CPU_64_BITS
+@@ -21,19 +21,23 @@
+ #define OS_LINUX 1
+ #elif defined(_WIN32)
+ #define OS_WIN 1
++#elif defined(__sun__) || defined(__sun)
++#define OS_SOLARIS 1
+ #else
+ #error Please add support for your platform in build/build_config.h
+ #endif
+ 
+ // For access to standard POSIX features, use OS_POSIX instead of a more
+ // specific macro.
+-#if defined(OS_MACOSX) || defined(OS_LINUX)
++#if defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_SOLARIS)
+ #define OS_POSIX 1
+ #endif
+ 
+ // Compiler detection.
+ #if defined(__GNUC__)
+ #define COMPILER_GCC 1
++#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
++#define COMPILER_SUNPRO 1
+ #elif defined(_MSC_VER)
+ #define COMPILER_MSVC 1
+ #else
+@@ -44,11 +48,11 @@
+ //   http://msdn.microsoft.com/en-us/library/b0084kay.aspx
+ //   http://www.agner.org/optimize/calling_conventions.pdf
+ //   or with gcc, run: "echo | gcc -E -dM -"
+-#if defined(_M_X64) || defined(__x86_64__)
++#if defined(_M_X64) || defined(__x86_64__) || defined(__x86_64)
+ #define ARCH_CPU_X86_FAMILY 1
+ #define ARCH_CPU_X86_64 1
+ #define ARCH_CPU_64_BITS 1
+-#elif defined(_M_IX86) || defined(__i386__)
++#elif defined(_M_IX86) || defined(__i386__) || defined(__i386)
+ #define ARCH_CPU_X86_FAMILY 1
+ #define ARCH_CPU_X86 1
+ #define ARCH_CPU_32_BITS 1
+@@ -60,6 +64,14 @@
+ #elif defined(__ppc__) || defined(__powerpc__)
+ #define ARCH_CPU_PPC 1
+ #define ARCH_CPU_32_BITS 1
++#elif defined(__sparc)
++#define ARCH_CPU_SPARC_FAMILY 1
++#define ARCH_CPU_SPARC 1
++#define ARCH_CPU_32_BITS 1
++#elif defined(__sparcv9)
++#define ARCH_CPU_SPARC_FAMILY 1
++#define ARCH_CPU_SPARC 1
++#define ARCH_CPU_64_BITS 1
+ #else
+ #error Please add support for your architecture in build/build_config.h
+ #endif
+diff --git a/ipc/chromium/src/chrome/common/chrome_constants.cc b/ipc/chromium/src/chrome/common/chrome_constants.cc
+index 2ca8f0c..162b57f 100644
+--- a/ipc/chromium/src/chrome/common/chrome_constants.cc
++++ b/ipc/chromium/src/chrome/common/chrome_constants.cc
+@@ -14,7 +14,7 @@ namespace chrome {
+ // for system strings only. UI changes should be made in the GRD.
+ #if defined(OS_WIN)
+ const wchar_t kBrowserProcessExecutableName[] = L"chrome.exe";
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+ const wchar_t kBrowserProcessExecutableName[] = L"chrome";
+ #elif defined(OS_MACOSX)
+ const wchar_t kBrowserProcessExecutableName[] =
+@@ -26,7 +26,7 @@ const wchar_t kBrowserProcessExecutableName[] =
+ #endif  // OS_*
+ #if defined(OS_WIN)
+ const wchar_t kBrowserProcessExecutablePath[] = L"chrome.exe";
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+ const wchar_t kBrowserProcessExecutablePath[] = L"chrome";
+ #elif defined(OS_MACOSX)
+ const wchar_t kBrowserProcessExecutablePath[] =
+diff --git a/ipc/chromium/src/chrome/common/chrome_paths.cc b/ipc/chromium/src/chrome/common/chrome_paths.cc
+index 2414306..e8cd9be 100644
+--- a/ipc/chromium/src/chrome/common/chrome_paths.cc
++++ b/ipc/chromium/src/chrome/common/chrome_paths.cc
+@@ -113,7 +113,7 @@ bool PathProvider(int key, FilePath* result) {
+       create_dir = true;
+       break;
+     case chrome::DIR_APP_DICTIONARIES:
+-#if defined(OS_LINUX)
++#if defined(OS_LINUX) || defined(OS_SOLARIS)
+       // We can't write into the EXE dir on Linux, so keep dictionaries
+       // alongside the safe browsing database in the user data dir.
+       if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
+diff --git a/ipc/chromium/src/chrome/common/file_descriptor_set_posix.cc b/ipc/chromium/src/chrome/common/file_descriptor_set_posix.cc
+index 49d8199..006b483 100644
+--- a/ipc/chromium/src/chrome/common/file_descriptor_set_posix.cc
++++ b/ipc/chromium/src/chrome/common/file_descriptor_set_posix.cc
+@@ -4,6 +4,10 @@
+ 
+ #include "chrome/common/file_descriptor_set_posix.h"
+ 
++#if defined(OS_SOLARIS)
++#include <unistd.h>
++#endif
++
+ #include "base/eintr_wrapper.h"
+ #include "base/logging.h"
+ 
+diff --git a/ipc/chromium/src/chrome/common/ipc_channel_posix.h b/ipc/chromium/src/chrome/common/ipc_channel_posix.h
+index 1302d58..0d450d6 100644
+--- a/ipc/chromium/src/chrome/common/ipc_channel_posix.h
++++ b/ipc/chromium/src/chrome/common/ipc_channel_posix.h
+@@ -92,7 +92,7 @@ class Channel::ChannelImpl : public MessageLoopForIO::Watcher {
+   };
+ 
+   // This is a control message buffer large enough to hold kMaxReadFDs
+-#if defined(OS_MACOSX)
++#if defined(OS_MACOSX) || defined(OS_SOLARIS)
+   // TODO(agl): OSX appears to have non-constant CMSG macros!
+   char input_cmsg_buf_[1024];
+ #else
+diff --git a/ipc/chromium/src/chrome/common/ipc_message.h b/ipc/chromium/src/chrome/common/ipc_message.h
+index 5cff474..c4e890f 100644
+--- a/ipc/chromium/src/chrome/common/ipc_message.h
++++ b/ipc/chromium/src/chrome/common/ipc_message.h
+@@ -289,7 +289,11 @@ class Message : public Pickle {
+ #endif
+   };
+ 
++#if defined(COMPILER_SUNPRO)
++#pragma pack (2)
++#else
+ #pragma pack(push, 2)
++#endif
+   struct Header : Pickle::Header {
+     int32 routing;  // ID of the view that this message is destined for
+     msgid_t type;   // specifies the user-defined message type
+@@ -310,7 +314,11 @@ class Message : public Pickle {
+     int32 seqno;
+ #endif
+   };
++#if defined(COMPILER_SUNPRO)
++#pragma pack (0)
++#else
+ #pragma pack(pop)
++#endif
+ 
+   Header* header() {
+     return headerT<Header>();
+diff --git a/ipc/chromium/src/chrome/common/ipc_message_utils.h b/ipc/chromium/src/chrome/common/ipc_message_utils.h
+index c4e0856..097f2da 100644
+--- a/ipc/chromium/src/chrome/common/ipc_message_utils.h
++++ b/ipc/chromium/src/chrome/common/ipc_message_utils.h
+@@ -219,7 +219,7 @@
+   }
+ };
+ 
+-#if !(defined(OS_MACOSX) || defined(OS_WIN) || (defined(CHROMIUM_MOZILLA_BUILD) && defined(OS_LINUX) && defined(ARCH_CPU_64_BITS)))
++#if !(defined(OS_MACOSX) || defined(OS_WIN) || (defined(CHROMIUM_MOZILLA_BUILD) && (defined(OS_LINUX) || defined(OS_SOLARIS)) && defined(ARCH_CPU_64_BITS)))
+ // There size_t is a synonym for |unsigned long| ...
+ template <>
+ struct ParamTraits<size_t> {
+@@ -252,7 +252,7 @@
+   }
+ };
+ 
+-#endif // if !(defined(OS_LINUX) && defined(ARCH_CPU_64_BITS))
++#endif // if !((defined(OS_LINUX) || defined(OS_SOLARIS)) && defined(ARCH_CPU_64_BITS))
+ 
+ #if defined(OS_MACOSX)
+ // On Linux size_t & uint32 can be the same type.
+@@ -272,7 +272,7 @@
+ };
+ #endif  // defined(OS_MACOSX)
+ 
+-#if !(defined(CHROMIUM_MOZILLA_BUILD) && defined(OS_LINUX) && defined(ARCH_CPU_64_BITS))
++#if !(defined(CHROMIUM_MOZILLA_BUILD) && (defined(OS_LINUX) || defined(OS_SOLARIS)) && defined(ARCH_CPU_64_BITS))
+ // int64 is |long int| on 64-bit systems, uint64 is |unsigned long|
+ template <>
+ struct ParamTraits<int64> {
+@@ -309,7 +309,7 @@
+ #endif // ifndef CHROMIUM_MOZILLA_BUILD
+   }
+ };
+-#endif // if !(defined(CHROMIUM_MOZILLA_BUILD) && defined(OS_LINUX) && defined(ARCH_CPU_64_BITS))
++#endif // if !(defined(CHROMIUM_MOZILLA_BUILD) && (defined(OS_LINUX) || defined(OS_SOLARIS)) && defined(ARCH_CPU_64_BITS))
+ 
+ template <>
+ struct ParamTraits<double> {
+diff --git a/ipc/chromium/src/chrome/common/native_web_keyboard_event.h b/ipc/chromium/src/chrome/common/native_web_keyboard_event.h
+index 0400b41..a462baf 100644
+--- a/ipc/chromium/src/chrome/common/native_web_keyboard_event.h
++++ b/ipc/chromium/src/chrome/common/native_web_keyboard_event.h
+@@ -16,7 +16,7 @@
+ #else
+ class NSEvent;
+ #endif  // __OBJC__
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+ #include <gdk/gdk.h>
+ #endif
+ 
+@@ -29,8 +29,8 @@ struct NativeWebKeyboardEvent : public WebKit::WebKeyboardEvent {
+   NativeWebKeyboardEvent(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
+ #elif defined(OS_MACOSX)
+   explicit NativeWebKeyboardEvent(NSEvent *event);
+-#elif defined(OS_LINUX)
+-  explicit NativeWebKeyboardEvent(const GdkEventKey* event);
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
++  explicit NativeWebKeyboardEvent(c onst GdkEventKey* event);
+ #endif
+ 
+   NativeWebKeyboardEvent(const NativeWebKeyboardEvent& event);
+@@ -42,7 +42,7 @@ struct NativeWebKeyboardEvent : public WebKit::WebKeyboardEvent {
+   MSG os_event;
+ #elif defined(OS_MACOSX)
+   NSEvent* os_event;
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+   GdkEventKey* os_event;
+ #endif
+ };
+diff --git a/ipc/chromium/src/chrome/common/temp_scaffolding_stubs.cc b/ipc/chromium/src/chrome/common/temp_scaffolding_stubs.cc
+index b4d87c8..e49e9e4 100644
+--- a/ipc/chromium/src/chrome/common/temp_scaffolding_stubs.cc
++++ b/ipc/chromium/src/chrome/common/temp_scaffolding_stubs.cc
+@@ -121,7 +121,7 @@ void AutomationProvider::OnMessageFromExternalHost(
+ 
+ //--------------------------------------------------------------------------
+ 
+-#if defined(OS_LINUX)
++#if defined(OS_LINUX) || defined(OS_SOLARIS)
+ bool ShellIntegration::SetAsDefaultBrowser() {
+   NOTIMPLEMENTED();
+   return true;
+diff --git a/ipc/chromium/src/chrome/common/transport_dib.h b/ipc/chromium/src/chrome/common/transport_dib.h
+index 33c0649..c690f89 100644
+--- a/ipc/chromium/src/chrome/common/transport_dib.h
++++ b/ipc/chromium/src/chrome/common/transport_dib.h
+@@ -13,7 +13,7 @@
+ 
+ #if defined(OS_WIN)
+ #include <windows.h>
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+ #include "chrome/common/x11_util.h"
+ #endif
+ 
+@@ -70,7 +70,7 @@ class TransportDIB {
+   typedef base::SharedMemoryHandle Handle;
+   // On Mac, the inode number of the backing file is used as an id.
+   typedef base::SharedMemoryId Id;
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+   typedef int Handle;  // These two ints are SysV IPC shared memory keys
+   typedef int Id;
+ #endif
+@@ -100,7 +100,7 @@ class TransportDIB {
+   // wire to give this transport DIB to another process.
+   Handle handle() const;
+ 
+-#if defined(OS_LINUX)
++#if defined(OS_LINUX) || defined(OS_SOLARIS)
+   // Map the shared memory into the X server and return an id for the shared
+   // segment.
+   XID MapToX(Display* connection);
+@@ -112,7 +112,7 @@ class TransportDIB {
+   explicit TransportDIB(base::SharedMemoryHandle dib);
+   base::SharedMemory shared_memory_;
+   uint32 sequence_num_;
+-#elif defined(OS_LINUX)
++#elif defined(OS_LINUX) || defined(OS_SOLARIS)
+   int key_;  // SysV shared memory id
+   void* address_;  // mapped address
+   XID x_shm_;  // X id for the shared segment
+diff --git a/ipc/chromium/src/third_party/libevent/linux/config.h b/ipc/chromium/src/third_party/libevent/linux/config.h
+index 9af92cc..fd92ec9 100644
+--- a/ipc/chromium/src/third_party/libevent/linux/config.h
++++ b/ipc/chromium/src/third_party/libevent/linux/config.h
+@@ -16,11 +16,13 @@
+ /* Define to 1 if you have the <dlfcn.h> header file. */
+ #define HAVE_DLFCN_H 1
+ 
++#ifndef OS_SOLARIS
+ /* Define if your system supports the epoll system calls */
+ #define HAVE_EPOLL 1
+ 
+ /* Define to 1 if you have the `epoll_ctl' function. */
+ #define HAVE_EPOLL_CTL 1
++#endif
+ 
+ /* Define if your system supports event ports */
+ /* #undef HAVE_EVENT_PORTS */
+diff --git a/ipc/glue/BrowserProcessSubThread.cpp b/ipc/glue/BrowserProcessSubThread.cpp
+index e51db3c..6c0eb32 100644
+--- a/ipc/glue/BrowserProcessSubThread.cpp
++++ b/ipc/glue/BrowserProcessSubThread.cpp
+@@ -57,7 +57,7 @@ static const char* kBrowserThreadNames[BrowserProcessSubThread::ID_COUNT] = {
+ //  "Chrome_FileThread",  // FILE
+ //  "Chrome_DBThread",  // DB
+ //  "Chrome_HistoryThread",  // HISTORY
+-#if defined(OS_LINUX)
++#if defined(OS_LINUX) || defined(OS_SOLARIS)
+   "Gecko_Background_X11Thread",  // BACKGROUND_X11
+ #endif
+ };
+@@ -68,7 +68,7 @@ BrowserProcessSubThread* BrowserProcessSubThread::sBrowserThreads[ID_COUNT] = {
+ //  NULL,  // FILE
+ //  NULL,  // DB
+ //  NULL,  // HISTORY
+-#if defined(OS_LINUX)
++#if defined(OS_LINUX) || defined(OS_SOLARIS)
+   NULL,  // BACKGROUND_X11
+ #endif
+ };
+diff --git a/ipc/glue/BrowserProcessSubThread.h b/ipc/glue/BrowserProcessSubThread.h
+index 68c8973..26bf0b3 100644
+--- a/ipc/glue/BrowserProcessSubThread.h
++++ b/ipc/glue/BrowserProcessSubThread.h
+@@ -60,7 +60,7 @@ public:
+       //FILE,
+       //DB,
+       //HISTORY,
+-#if defined(OS_LINUX)
++#if defined(OS_LINUX) || defined(OS_SOLARIS)
+       // This thread has a second connection to the X server and is used
+       // to process UI requests when routing the request to the UI
+       // thread would risk deadlock.
+diff --git a/ipc/glue/GeckoChildProcessHost.cpp b/ipc/glue/GeckoChildProcessHost.cpp
+index 67a9651..47e9363 100644
+--- a/ipc/glue/GeckoChildProcessHost.cpp
++++ b/ipc/glue/GeckoChildProcessHost.cpp
+@@ -459,7 +459,7 @@ GeckoChildProcessHost::PerformAsyncLaunch(std::vector<std::string> aExtraOpts, b
+   childArgv.push_back(pidstring);
+ 
+ #if defined(MOZ_CRASHREPORTER)
+-#  if defined(OS_LINUX)
++#  if defined(OS_LINUX) || defined(OS_SOLARIS)
+   int childCrashFd, childCrashRemapFd;
+   if (!CrashReporter::CreateNotificationPipeForChild(
+         &childCrashFd, &childCrashRemapFd))
+@@ -475,7 +475,7 @@ GeckoChildProcessHost::PerformAsyncLaunch(std::vector<std::string> aExtraOpts, b
+   }
+ #  elif defined(XP_MACOSX)
+   childArgv.push_back(CrashReporter::GetChildNotificationPipe());
+-#  endif  // OS_LINUX
++#  endif  // OS_LINUX || defined(OS_SOLARIS)
+ #endif
+ 
+ #ifdef XP_MACOSX
+@@ -498,6 +498,8 @@ GeckoChildProcessHost::PerformAsyncLaunch(std::vector<std::string> aExtraOpts, b
+   base::LaunchApp(childArgv, mFileMap,
+ #if defined(OS_LINUX) || defined(OS_MACOSX)
+                   newEnvVars,
++#elif defined(OS_SOLARIS)
++                  base::environment_map(),
+ #endif
+                   false, &process, arch);
+ 
+diff --git a/ipc/glue/SharedMemorySysV.h b/ipc/glue/SharedMemorySysV.h
+index a68b22b..1df19ef 100644
+--- a/ipc/glue/SharedMemorySysV.h
++++ b/ipc/glue/SharedMemorySysV.h
+@@ -40,7 +40,7 @@
+ #ifndef mozilla_ipc_SharedMemorySysV_h
+ #define mozilla_ipc_SharedMemorySysV_h
+ 
+-#if defined(OS_LINUX) && !defined(ANDROID)
++#if (defined(OS_LINUX) || defined(OS_SOLARIS)) && !defined(ANDROID)
+ 
+ // SysV shared memory isn't available on Windows, but we define the
+ // following macro so that #ifdefs are clearer (compared to #ifdef
+@@ -87,6 +87,9 @@ public:
+   virtual ~SharedMemorySysV()
+   {
+     shmdt(mData);
++#ifdef OS_SOLARIS    
++    shmctl(mHandle, IPC_RMID, 0);
++#endif    
+     mHandle = -1;
+     mData = nsnull;
+   }
+@@ -128,7 +131,9 @@ public:
+ 
+     // Mark the handle as deleted so that, should this process go away, the
+     // segment is cleaned up.
++#ifndef OS_SOLARIS
+     shmctl(mHandle, IPC_RMID, 0);
++#endif
+ 
+     mData = mem;
+ 
+@@ -181,6 +186,6 @@ private:
+ } // namespace ipc
+ } // namespace mozilla
+ 
+-#endif // OS_LINUX
++#endif // OS_LINUX || OS_SOLARIS
+ 
+ #endif // ifndef mozilla_ipc_SharedMemorySysV_h
+diff --git a/ipc/ipdl/test/cxx/Makefile.in b/ipc/ipdl/test/cxx/Makefile.in
+index c244534..ceca18a 100644
+--- a/ipc/ipdl/test/cxx/Makefile.in
++++ b/ipc/ipdl/test/cxx/Makefile.in
+@@ -87,6 +87,10 @@ ifeq ($(OS_ARCH),Linux)
+ IPDLTESTS += TestSysVShmem
+ endif
+ 
++ifeq ($(OS_ARCH),SunOS)
++IPDLTESTS += TestSysVShmem
++endif
++
+ IPDLTESTSRCS = $(addsuffix .cpp,$(IPDLTESTS))
+ IPDLTESTHDRS = $(addprefix $(srcdir)/,$(addsuffix .h,$(IPDLTESTS)))
+ 
+diff --git a/ipc/ipdl/test/cxx/TestShutdown.cpp b/ipc/ipdl/test/cxx/TestShutdown.cpp
+index 217aabc..6fe4dbd 100644
+--- a/ipc/ipdl/test/cxx/TestShutdown.cpp
++++ b/ipc/ipdl/test/cxx/TestShutdown.cpp
+@@ -184,6 +184,8 @@ TestShutdownChild::RecvStart()
+         // detectors
+         _exit(0);
+     }
++
++    return false;
+ }
+ 
+ void
+diff --git a/layout/base/nsPresArena.cpp b/layout/base/nsPresArena.cpp
+index 4456cd1..7e23a5d 100644
+--- a/layout/base/nsPresArena.cpp
++++ b/layout/base/nsPresArena.cpp
+@@ -82,6 +82,8 @@
+ # endif
+ #endif
+ 
++extern "C" int madvise(caddr_t, size_t, int);
++
+ // Size to use for PLArena block allocations.
+ static const size_t ARENA_PAGE_SIZE = 4096;
+ 
+diff --git a/layout/base/tests/TestPoisonArea.cpp b/layout/base/tests/TestPoisonArea.cpp
+index 20cf9ed..646fd13 100644
+--- a/layout/base/tests/TestPoisonArea.cpp
++++ b/layout/base/tests/TestPoisonArea.cpp
+@@ -149,6 +149,7 @@ typedef unsigned int uint32_t;
+ #include <sys/wait.h>
+ 
+ #include <sys/mman.h>
++extern "C" int madvise(caddr_t, size_t, int);
+ #ifndef MAP_ANON
+ #ifdef MAP_ANONYMOUS
+ #define MAP_ANON MAP_ANONYMOUS
+diff --git a/xpcom/io/nsFastLoadFile.cpp b/xpcom/io/nsFastLoadFile.cpp
+index aaf7dcb..0aca1e4 100644
+--- a/xpcom/io/nsFastLoadFile.cpp
++++ b/xpcom/io/nsFastLoadFile.cpp
+@@ -58,6 +58,7 @@
+ #include "nsFastLoadFile.h"
+ #ifdef XP_UNIX
+ #include <sys/mman.h>
++extern  "C" int madvise(caddr_t, size_t, int);
+ #endif
+ 
+ #ifdef DEBUG_brendan
+diff --git a/ipc/chromium/src/base/file_util_deprecated.h b/ipc/chromium/src/base/file_util_deprecated.h
+new file mode 100644
+index 0000000..9a8c5bf
+--- /dev/null
++++ b/ipc/chromium/src/base/file_util_deprecated.h
+@@ -0,0 +1,74 @@
++// Copyright (c) 2010 The Chromium Authors. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++// We're trying to transition away from paths as wstrings into using
++// FilePath objects.  This file contains declarations of deprecated
++// functions.  By hiding them here rather in the main header, we hope
++// to discourage callers.
++
++// See file_util.h for documentation on all functions that don't have
++// documentation here.
++
++#ifndef BASE_FILE_UTIL_DEPRECATED_H_
++#define BASE_FILE_UTIL_DEPRECATED_H_
++
++#include "build/build_config.h"
++
++namespace file_util {
++
++bool EndsWithSeparator(std::wstring* path);
++bool EndsWithSeparator(const std::wstring& path);
++
++// Use FilePath::DirName instead.
++void UpOneDirectory(std::wstring* dir);
++// Use FilePath::DirName instead.
++void UpOneDirectoryOrEmpty(std::wstring* dir);
++
++// Use FilePath::BaseName instead.
++std::wstring GetFilenameFromPath(const std::wstring& path);
++
++// Use FilePath::Extension instead.
++FilePath::StringType GetFileExtensionFromPath(const FilePath& path);
++std::wstring GetFileExtensionFromPath(const std::wstring& path);
++
++bool AbsolutePath(std::wstring* path);
++
++// Use FilePath::InsertBeforeExtension.
++void InsertBeforeExtension(FilePath* path, const FilePath::StringType& suffix);
++
++// Use FilePath::ReplaceExtension.
++void ReplaceExtension(FilePath* file_name,
++                      const FilePath::StringType& extension);
++
++bool Delete(const std::wstring& path, bool recursive);
++bool CopyDirectory(const std::wstring& from_path, const std::wstring& to_path,
++                   bool recursive);
++bool ReadFileToString(const std::wstring& path, std::string* contents);
++FILE* OpenFile(const std::string& filename, const char* mode);
++FILE* OpenFile(const std::wstring& filename, const char* mode);
++int ReadFile(const std::wstring& filename, char* data, int size);
++int WriteFile(const std::wstring& filename, const char* data, int size);
++
++// Functions successfully deprecated on non-Windows, but Win-specific
++// callers remain.
++#if defined(OS_WIN)
++// Returns the directory component of a path, without the trailing
++// path separator, or an empty string on error. The function does not
++// check for the existence of the path, so if it is passed a directory
++// without the trailing \, it will interpret the last component of the
++// path as a file and chomp it. This does not support relative paths.
++// Examples:
++// path == "C:\pics\jojo.jpg",     returns "C:\pics"
++// path == "C:\Windows\system32\", returns "C:\Windows\system32"
++// path == "C:\Windows\system32",  returns "C:\Windows"
++// Deprecated. Use FilePath's DirName() instead.
++std::wstring GetDirectoryFromPath(const std::wstring& path);
++
++// Appends new_ending to path, adding a separator between the two if necessary.
++void AppendToPath(std::wstring* path, const std::wstring& new_ending);
++#endif
++
++}
++
++#endif  // BASE_FILE_UTIL_DEPRECATED_H_
+diff --git a/ipc/chromium/src/base/third_party/nspr/prcpucfg_solaris.h b/ipc/chromium/src/base/third_party/nspr/prcpucfg_solaris.h
+new file mode 100644
+index 0000000..81313e5
+--- /dev/null
++++ b/ipc/chromium/src/base/third_party/nspr/prcpucfg_solaris.h
+@@ -0,0 +1,203 @@
++/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is the Netscape Portable Runtime (NSPR).
++ *
++ * The Initial Developer of the Original Code is
++ * Netscape Communications Corporation.
++ * Portions created by the Initial Developer are Copyright (C) 1998-2000
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#ifndef nspr_cpucfg___
++#define nspr_cpucfg___
++
++#ifndef XP_UNIX
++#define XP_UNIX
++#endif
++
++#ifndef SOLARIS
++#define SOLARIS
++#endif
++
++#define PR_AF_INET6 26  /* same as AF_INET6 */
++
++#if defined(sparc) || defined(__sparc)
++#undef  IS_LITTLE_ENDIAN
++#define IS_BIG_ENDIAN 1
++#define PR_ALIGN_OF_INT64   8
++#define PR_ALIGN_OF_DOUBLE  8
++#if defined(__sparcv9)
++#define IS_64
++#endif
++#elif defined(__x86_64)
++#define IS_LITTLE_ENDIAN 1
++#undef  IS_BIG_ENDIAN
++#define PR_ALIGN_OF_INT64   8
++#define PR_ALIGN_OF_DOUBLE  8
++#define IS_64
++#elif defined(i386) || defined(__i386)
++#define IS_LITTLE_ENDIAN 1
++#undef  IS_BIG_ENDIAN
++#define PR_ALIGN_OF_INT64   4
++#define PR_ALIGN_OF_DOUBLE  4
++#else
++#error unknown processor
++#endif
++
++#ifdef IS_64
++
++#define PR_BYTES_PER_BYTE   1
++#define PR_BYTES_PER_SHORT  2
++#define PR_BYTES_PER_INT    4
++#define PR_BYTES_PER_INT64  8
++#define PR_BYTES_PER_LONG   8
++#define PR_BYTES_PER_FLOAT  4
++#define PR_BYTES_PER_DOUBLE 8
++#define PR_BYTES_PER_WORD   8
++#define PR_BYTES_PER_DWORD  8
++#define PR_BYTES_PER_WORD_LOG2   3
++#define PR_BYTES_PER_DWORD_LOG2  3
++
++#define PR_BITS_PER_BYTE    8
++#define PR_BITS_PER_SHORT   16
++#define PR_BITS_PER_INT     32
++#define PR_BITS_PER_INT64   64
++#define PR_BITS_PER_LONG    64
++#define PR_BITS_PER_FLOAT   32
++#define PR_BITS_PER_DOUBLE  64
++#define PR_BITS_PER_WORD    64
++
++#define PR_BITS_PER_BYTE_LOG2   3
++#define PR_BITS_PER_SHORT_LOG2  4
++#define PR_BITS_PER_INT_LOG2    5
++#define PR_BITS_PER_INT64_LOG2  6
++#define PR_BITS_PER_LONG_LOG2   6
++#define PR_BITS_PER_FLOAT_LOG2  5
++#define PR_BITS_PER_DOUBLE_LOG2 6
++#define PR_BITS_PER_WORD_LOG2   6
++
++#define PR_ALIGN_OF_SHORT   2
++#define PR_ALIGN_OF_INT     4
++#define PR_ALIGN_OF_LONG    8
++#define PR_ALIGN_OF_FLOAT   4
++#define PR_ALIGN_OF_POINTER 8
++
++#else /* IS_64 */
++
++#define PR_BYTES_PER_BYTE   1
++#define PR_BYTES_PER_SHORT  2
++#define PR_BYTES_PER_INT    4
++#define PR_BYTES_PER_INT64  8
++#define PR_BYTES_PER_LONG   4
++#define PR_BYTES_PER_FLOAT  4
++#define PR_BYTES_PER_DOUBLE 8
++#define PR_BYTES_PER_WORD   4
++#define PR_BYTES_PER_DWORD  8
++#define PR_BYTES_PER_WORD_LOG2   2
++#define PR_BYTES_PER_DWORD_LOG2  3
++
++#define PR_BITS_PER_BYTE    8
++#define PR_BITS_PER_SHORT   16
++#define PR_BITS_PER_INT     32
++#define PR_BITS_PER_INT64   64
++#define PR_BITS_PER_LONG    32
++#define PR_BITS_PER_FLOAT   32
++#define PR_BITS_PER_DOUBLE  64
++#define PR_BITS_PER_WORD    32
++
++#define PR_BITS_PER_BYTE_LOG2   3
++#define PR_BITS_PER_SHORT_LOG2  4
++#define PR_BITS_PER_INT_LOG2    5
++#define PR_BITS_PER_INT64_LOG2  6
++#define PR_BITS_PER_LONG_LOG2   5
++#define PR_BITS_PER_FLOAT_LOG2  5
++#define PR_BITS_PER_DOUBLE_LOG2 6
++#define PR_BITS_PER_WORD_LOG2   5
++
++#define PR_ALIGN_OF_SHORT   2
++#define PR_ALIGN_OF_INT     4
++#define PR_ALIGN_OF_LONG    4
++#define PR_ALIGN_OF_FLOAT   4
++#define PR_ALIGN_OF_POINTER 4
++
++#endif /* IS_64 */
++
++#ifndef HAVE_LONG_LONG
++#define	HAVE_LONG_LONG
++#endif
++#define	HAVE_ALIGNED_DOUBLES
++#define	HAVE_ALIGNED_LONGLONGS
++
++#ifndef NO_NSPR_10_SUPPORT
++
++#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
++#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
++#define BYTES_PER_INT 		PR_BYTES_PER_INT
++#define BYTES_PER_INT64		PR_BYTES_PER_INT64
++#define BYTES_PER_LONG		PR_BYTES_PER_LONG
++#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
++#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
++#define BYTES_PER_WORD		PR_BYTES_PER_WORD
++#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
++
++#define BITS_PER_BYTE		PR_BITS_PER_BYTE
++#define BITS_PER_SHORT		PR_BITS_PER_SHORT
++#define BITS_PER_INT		PR_BITS_PER_INT
++#define BITS_PER_INT64		PR_BITS_PER_INT64
++#define BITS_PER_LONG		PR_BITS_PER_LONG
++#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
++#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
++#define BITS_PER_WORD		PR_BITS_PER_WORD
++
++#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
++#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
++#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
++#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
++#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
++#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
++#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
++#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
++
++#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
++#define ALIGN_OF_INT		PR_ALIGN_OF_INT
++#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
++#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
++#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
++#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
++#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
++#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
++
++#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
++#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
++#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
++
++#endif /* NO_NSPR_10_SUPPORT */
++
++#endif /* ifndef nspr_cpucfg___ */
+diff --git a/ipc/chromium/src/third_party/libevent/solaris/config.h b/ipc/chromium/src/third_party/libevent/solaris/config.h
+new file mode 100644
+index 0000000..2e2a78a
+--- /dev/null
++++ b/ipc/chromium/src/third_party/libevent/solaris/config.h
+@@ -0,0 +1,254 @@
++/* config.h.  Generated from config.h.in by configure.  */
++/* config.h.in.  Generated from configure.in by autoheader.  */
++
++/* Define if clock_gettime is available in libc */
++#define DNS_USE_CPU_CLOCK_FOR_ID 1
++
++/* Define is no secure id variant is available */
++/* #undef DNS_USE_GETTIMEOFDAY_FOR_ID */
++
++/* Define to 1 if you have the `clock_gettime' function. */
++#define HAVE_CLOCK_GETTIME 1
++
++/* Define if /dev/poll is available */
++#define HAVE_DEVPOLL 1
++
++/* Define to 1 if you have the <dlfcn.h> header file. */
++#define HAVE_DLFCN_H 1
++
++/* Define if your system supports the epoll system calls */
++/* #undef HAVE_EPOLL */
++
++/* Define to 1 if you have the `epoll_ctl' function. */
++/* #undef HAVE_EPOLL_CTL */
++
++/* Define if your system supports event ports */
++#define HAVE_EVENT_PORTS 1
++
++/* Define to 1 if you have the `fcntl' function. */
++#define HAVE_FCNTL 1
++
++/* Define to 1 if you have the <fcntl.h> header file. */
++#define HAVE_FCNTL_H 1
++
++/* Define to 1 if you have the `getaddrinfo' function. */
++#define HAVE_GETADDRINFO 1
++
++/* Define to 1 if you have the `getnameinfo' function. */
++#define HAVE_GETNAMEINFO 1
++
++/* Define to 1 if you have the `gettimeofday' function. */
++#define HAVE_GETTIMEOFDAY 1
++
++/* Define to 1 if you have the `inet_ntop' function. */
++#define HAVE_INET_NTOP 1
++
++/* Define to 1 if you have the <inttypes.h> header file. */
++#define HAVE_INTTYPES_H 1
++
++/* Define to 1 if you have the `kqueue' function. */
++/* #undef HAVE_KQUEUE */
++
++/* Define to 1 if you have the `nsl' library (-lnsl). */
++#define HAVE_LIBNSL 1
++
++/* Define to 1 if you have the `resolv' library (-lresolv). */
++#define HAVE_LIBRESOLV 1
++
++/* Define to 1 if you have the `rt' library (-lrt). */
++#define HAVE_LIBRT 1
++
++/* Define to 1 if you have the `socket' library (-lsocket). */
++#define HAVE_LIBSOCKET 1
++
++/* Define to 1 if you have the <memory.h> header file. */
++#define HAVE_MEMORY_H 1
++
++/* Define to 1 if you have the <netinet/in6.h> header file. */
++/* #undef HAVE_NETINET_IN6_H */
++
++/* Define to 1 if you have the `poll' function. */
++#define HAVE_POLL 1
++
++/* Define to 1 if you have the <poll.h> header file. */
++#define HAVE_POLL_H 1
++
++/* Define to 1 if you have the `port_create' function. */
++#define HAVE_PORT_CREATE 1
++
++/* Define to 1 if you have the <port.h> header file. */
++#define HAVE_PORT_H 1
++
++/* Define to 1 if you have the `select' function. */
++#define HAVE_SELECT 1
++
++/* Define if F_SETFD is defined in <fcntl.h> */
++#define HAVE_SETFD 1
++
++/* Define to 1 if you have the `sigaction' function. */
++#define HAVE_SIGACTION 1
++
++/* Define to 1 if you have the `signal' function. */
++#define HAVE_SIGNAL 1
++
++/* Define to 1 if you have the <signal.h> header file. */
++#define HAVE_SIGNAL_H 1
++
++/* Define to 1 if you have the <stdarg.h> header file. */
++#define HAVE_STDARG_H 1
++
++/* Define to 1 if you have the <stdint.h> header file. */
++#define HAVE_STDINT_H 1
++
++/* Define to 1 if you have the <stdlib.h> header file. */
++#define HAVE_STDLIB_H 1
++
++/* Define to 1 if you have the <strings.h> header file. */
++#define HAVE_STRINGS_H 1
++
++/* Define to 1 if you have the <string.h> header file. */
++#define HAVE_STRING_H 1
++
++/* Define to 1 if you have the `strlcpy' function. */
++#define HAVE_STRLCPY 1
++
++/* Define to 1 if you have the `strsep' function. */
++#define HAVE_STRSEP 1
++
++/* Define to 1 if you have the `strtok_r' function. */
++#define HAVE_STRTOK_R 1
++
++/* Define to 1 if you have the `strtoll' function. */
++#define HAVE_STRTOLL 1
++
++/* Define to 1 if the system has the type `struct in6_addr'. */
++#define HAVE_STRUCT_IN6_ADDR 1
++
++/* Define to 1 if you have the <sys/devpoll.h> header file. */
++#define HAVE_SYS_DEVPOLL_H 1
++
++/* Define to 1 if you have the <sys/epoll.h> header file. */
++/* #undef HAVE_SYS_EPOLL_H */
++
++/* Define to 1 if you have the <sys/event.h> header file. */
++/* #undef HAVE_SYS_EVENT_H */
++
++/* Define to 1 if you have the <sys/ioctl.h> header file. */
++#define HAVE_SYS_IOCTL_H 1
++
++/* Define to 1 if you have the <sys/param.h> header file. */
++#define HAVE_SYS_PARAM_H 1
++
++/* Define to 1 if you have the <sys/queue.h> header file. */
++#define HAVE_SYS_QUEUE_H 1
++
++/* Define to 1 if you have the <sys/select.h> header file. */
++#define HAVE_SYS_SELECT_H 1
++
++/* Define to 1 if you have the <sys/socket.h> header file. */
++#define HAVE_SYS_SOCKET_H 1
++
++/* Define to 1 if you have the <sys/stat.h> header file. */
++#define HAVE_SYS_STAT_H 1
++
++/* Define to 1 if you have the <sys/time.h> header file. */
++#define HAVE_SYS_TIME_H 1
++
++/* Define to 1 if you have the <sys/types.h> header file. */
++#define HAVE_SYS_TYPES_H 1
++
++/* Define if TAILQ_FOREACH is defined in <sys/queue.h> */
++#define HAVE_TAILQFOREACH 1
++
++/* Define if timeradd is defined in <sys/time.h> */
++#define HAVE_TIMERADD 1
++
++/* Define if timerclear is defined in <sys/time.h> */
++#define HAVE_TIMERCLEAR 1
++
++/* Define if timercmp is defined in <sys/time.h> */
++#define HAVE_TIMERCMP 1
++
++/* Define if timerisset is defined in <sys/time.h> */
++#define HAVE_TIMERISSET 1
++
++/* Define to 1 if the system has the type `uint16_t'. */
++#define HAVE_UINT16_T 1
++
++/* Define to 1 if the system has the type `uint32_t'. */
++#define HAVE_UINT32_T 1
++
++/* Define to 1 if the system has the type `uint64_t'. */
++#define HAVE_UINT64_T 1
++
++/* Define to 1 if the system has the type `uint8_t'. */
++#define HAVE_UINT8_T 1
++
++/* Define to 1 if you have the <unistd.h> header file. */
++#define HAVE_UNISTD_H 1
++
++/* Define to 1 if you have the `vasprintf' function. */
++#define HAVE_VASPRINTF 1
++
++/* Define if kqueue works correctly with pipes */
++/* #undef HAVE_WORKING_KQUEUE */
++
++/* Name of package */
++#define PACKAGE "libevent"
++
++/* Define to the address where bug reports for this package should be sent. */
++#define PACKAGE_BUGREPORT ""
++
++/* Define to the full name of this package. */
++#define PACKAGE_NAME ""
++
++/* Define to the full name and version of this package. */
++#define PACKAGE_STRING ""
++
++/* Define to the one symbol short name of this package. */
++#define PACKAGE_TARNAME ""
++
++/* Define to the version of this package. */
++#define PACKAGE_VERSION ""
++
++/* The size of `int', as computed by sizeof. */
++#define SIZEOF_INT 4
++
++/* The size of `long', as computed by sizeof. */
++#define SIZEOF_LONG 4
++
++/* The size of `long long', as computed by sizeof. */
++#define SIZEOF_LONG_LONG 8
++
++/* The size of `short', as computed by sizeof. */
++#define SIZEOF_SHORT 2
++
++/* Define to 1 if you have the ANSI C header files. */
++#define STDC_HEADERS 1
++
++/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
++#define TIME_WITH_SYS_TIME 1
++
++/* Version number of package */
++#define VERSION "1.4.7-stable"
++
++/* Define to appropriate substitue if compiler doesnt have __func__ */
++/* #undef __func__ */
++
++/* Define to empty if `const' does not conform to ANSI C. */
++/* #undef const */
++
++/* Define to `__inline__' or `__inline' if that's what the C compiler
++   calls it, or to nothing if 'inline' is not supported under any name.  */
++#ifndef __cplusplus
++/* #undef inline */
++#endif
++
++/* Define to `int' if <sys/types.h> does not define. */
++/* #undef pid_t */
++
++/* Define to `unsigned int' if <sys/types.h> does not define. */
++/* #undef size_t */
++
++/* Define to unsigned int if you dont have it */
++/* #undef socklen_t */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/firefox6-10-appname-tr.diff	Mon Aug 15 02:22:00 2011 +0000
@@ -0,0 +1,29 @@
+--- a/configure	Mon Jul 11 11:52:00 2011
++++ b/configure	Mon Jul 11 11:52:42 2011
+@@ -19056,7 +19056,7 @@
+ # Check whether --enable-update-channel or --disable-update-channel was given.
+ if test "${enable_update_channel+set}" = set; then
+   enableval="$enable_update_channel"
+-  MOZ_UPDATE_CHANNEL=`echo $enableval | tr A-Z a-z`
++  MOZ_UPDATE_CHANNEL=`echo $enableval | tr -s '[:upper:]' '[:lower:]'`
+ fi
+ 
+ 
+@@ -21655,7 +21655,7 @@
+ # Check whether --enable-chrome-format or --disable-chrome-format was given.
+ if test "${enable_chrome_format+set}" = set; then
+   enableval="$enable_chrome_format"
+-  MOZ_CHROME_FILE_FORMAT=`echo $enableval | tr A-Z a-z`
++  MOZ_CHROME_FILE_FORMAT=`echo $enableval | tr -s '[:upper:]' '[:lower:]'`
+ fi
+ 
+ 
+@@ -24613,7 +24613,7 @@
+ # "Profile" field, which controls profile location.
+ 
+ if test -z "$MOZ_APP_NAME"; then
+-   MOZ_APP_NAME=`echo $MOZ_APP_BASENAME | tr A-Z a-z`
++   MOZ_APP_NAME=`echo $MOZ_APP_BASENAME | tr -s '[:upper:]' '[:lower:]'`
+ fi
+ 
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/firefox6-12-xpcom-glue-no-hidden.diff	Mon Aug 15 02:22:00 2011 +0000
@@ -0,0 +1,24 @@
+diff --git a/xpcom/build/Makefile.in b/xpcom/build/Makefile.in
+index 2ff9f82..481d720 100644
+--- a/xpcom/build/Makefile.in
++++ b/xpcom/build/Makefile.in
+@@ -51,6 +51,7 @@
+ SHORT_LIBNAME	= xpcomcor
+ LIBXUL_LIBRARY = 1
+ EXPORT_LIBRARY = 1
++VISIBILITY_FLAGS =
+ 
+ GRE_MODULE	= 1
+ MOZILLA_INTERNAL_API = 1
+diff --git a/xpcom/glue/Makefile.in b/xpcom/glue/Makefile.in
+index 116f8cd..6c4415c 100644
+--- a/xpcom/glue/Makefile.in
++++ b/xpcom/glue/Makefile.in
+@@ -44,6 +44,7 @@ include $(DEPTH)/config/autoconf.mk
+ include $(srcdir)/objs.mk
+ 
+ EXTRA_DEPS += $(srcdir)/objs.mk
++VISIBILITY_FLAGS =
+ 
+ DIRS            = standalone nomozalloc
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/firefox6-13-gen-devel-files.diff	Mon Aug 15 02:22:00 2011 +0000
@@ -0,0 +1,21 @@
+diff --git a/browser/installer/Makefile.in b/browser/installer/Makefile.in
+index 690bb38..46edf48 100644
+--- a/browser/installer/Makefile.in
++++ b/browser/installer/Makefile.in
+@@ -155,3 +155,5 @@ installer:: removed-files
+ ifdef INSTALLER_DIR
+ 	$(MAKE) -C $(INSTALLER_DIR)
+ endif
++
++libs:: make-sdk
+--- a/toolkit/library/Makefile.in
++++ b/toolkit/library/Makefile.in
+@@ -140,7 +140,7 @@
+ endif
+ endif
+ 
+-EXTRA_DSO_LDOPTS += $(LIBS_DIR) $(EXTRA_DSO_LIBS)
++EXTRA_DSO_LDOPTS += $(LIBS_DIR) $(EXTRA_DSO_LIBS) $(MKSHLIB_FORCE_ALL) $(LIBXUL_DIST)/lib/$(LIB_PREFIX)xpcomglue_s.$(LIB_SUFFIX) $(MKSHLIB_UNFORCE_ALL)
+ 
+ DEFINES += -DIMPL_XREAPI
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/firefox6-14-getting-started.diff	Mon Aug 15 02:22:00 2011 +0000
@@ -0,0 +1,57 @@
+diff --git a/browser/base/content/aboutHome.xhtml b/browser/base/content/aboutHome.xhtml
+index 9b62b87..6db1ea5 100644
+--- a/browser/base/content/aboutHome.xhtml
++++ b/browser/base/content/aboutHome.xhtml
+@@ -85,7 +85,7 @@
+     </div>
+ 
+     <div id="contentContainer">
+-      <div id="snippetContainer">
++      <div id="snippetContainer" hidden="true">
+         <div id="defaultSnippets" hidden="true">
+           <span>&abouthome.defaultSnippet1.v1;</span>
+           <span>&abouthome.defaultSnippet2.v1;</span>
+@@ -96,6 +96,10 @@
+       <div id="sessionRestoreContainer">
+         <button id="restorePreviousSession">&historyRestoreLastSession.label;</button>
+       </div>
++
++      <div style="padding-top: 100px; text-align: center;">
++         <a href="http://www.oracle.com/"><img src="chrome://branding/content/ora_solaris.png" alt="" border="0" /></a>
++      </div>
+     </div>
+ 
+     <div id="bottomSection">
+diff --git a/browser/base/content/aboutHome.css b/browser/base/content/aboutHome.css
+index 99f8d3f..25b91f2 100644
+--- a/browser/base/content/aboutHome.css
++++ b/browser/base/content/aboutHome.css
+@@ -193,9 +193,9 @@ body[dir=rtl] #searchSubmit:active {
+ 
+ #contentContainer {
+   height: 30%;
+-  background-image: -moz-radial-gradient(center top, ellipse farthest-side, rgba(16,83,130,.5), rgba(16,83,130,0) 75%),
+-                    -moz-radial-gradient(center top, ellipse farthest-side, rgba(180,218,244,.5), rgba(180,218,244,0)),
+-                    -moz-radial-gradient(center top, ellipse farthest-side, rgba(180,218,244,.3), rgba(180,218,244,0));
++  background-image: -moz-radial-gradient(center top, ellipse farthest-side, rgba(9,9,9,.5), rgba(9,9,9,0) 75%),
++                    -moz-radial-gradient(center top, ellipse farthest-side, rgba(208,208,208,.5), rgba(208,208,208,0)),
++                    -moz-radial-gradient(center top, ellipse farthest-side, rgba(208,208,208,.3), rgba(208,208,208,0));
+   background-size: 100% 5px,
+                    100% 50px,
+                    100% 100%;
+--- a/browser/branding/official/pref/firefox-branding.js
+--- b/browser/branding/official/pref/firefox-branding.js
+@@ -1,5 +1,5 @@
+ pref("startup.homepage_override_url","http://www.mozilla.com/%LOCALE%/%APP%/%VERSION%/whatsnew/");
+-pref("startup.homepage_welcome_url","http://www.mozilla.com/%LOCALE%/%APP%/%VERSION%/firstrun/");
++pref("startup.homepage_welcome_url","file:///usr/share/doc/os-welcome/html/index.html");
+ // Interval: Time between checks for a new version (in seconds)
+ // nightly=6 hours, official=24 hours
+ pref("app.update.interval", 86400);
+--- a/browser/branding/official/content/jar.mn	2011-07-14 16:23:45.539579498 +0800
++++ b/browser/branding/official/content/jar.mn	2011-07-14 16:23:55.865704245 +0800
+@@ -8,3 +8,4 @@
+   content/branding/icon128.png                   (../mozicon128.png)
+   content/branding/icon16.png                    (../default16.png)
+   content/branding/aboutDialog.css               (aboutDialog.css)
++  content/branding/ora_solaris.png               (ora_solaris.png)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/firefox6-19-xpcom-sparc-compile.diff	Mon Aug 15 02:22:00 2011 +0000
@@ -0,0 +1,17 @@
+diff --git a/xpcom/tests/Makefile.in b/xpcom/tests/Makefile.in
+index bb031c9..68a7b8e 100644
+--- a/xpcom/tests/Makefile.in
++++ b/xpcom/tests/Makefile.in
+@@ -151,6 +151,12 @@
+ # Make sure we have symbols in case we need to debug these.
+ MOZ_DEBUG_SYMBOLS = 1
+ 
++ifdef SOLARIS_SUNPRO_CXX
++ifeq (sparc,$(findstring sparc,$(OS_TEST)))
++MOZ_OPTIMIZE_FLAGS = -xO3
++endif
++endif
++
+ include $(topsrcdir)/config/rules.mk
+ 
+ LOCAL_INCLUDES	= \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/firefox6-24-storage-test.diff	Mon Aug 15 02:22:00 2011 +0000
@@ -0,0 +1,20 @@
+commit d2c570f9fb9d6c6b4183680e4cb8afe200728c9e
+Author: Ginn Chen <[email protected]>
+Date:   Wed Mar 9 14:13:53 2011 +0800
+
+    firefox4-24-storage-test.diff
+
+diff --git a/storage/test/Makefile.in b/storage/test/Makefile.in
+index 8df8db1..a7198a7 100644
+--- a/storage/test/Makefile.in
++++ b/storage/test/Makefile.in
+@@ -81,8 +81,8 @@
+ 
+ LIBS = \
+ 	$(LIBS_DIR) \
+-	$(MOZ_COMPONENT_LIBS) \
+ 	$(SQLITE_LIBS) \
++	$(MOZ_COMPONENT_LIBS) \
+ 	$(NULL)
+ 
+ include $(topsrcdir)/config/rules.mk
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/firefox6-26-pgo-ss12_2.diff	Mon Aug 15 02:22:00 2011 +0000
@@ -0,0 +1,78 @@
+diff --git a/configure b/configure
+index e4a5249..21433e7 100755
+--- a/configure
++++ b/configure
+@@ -22139,8 +22139,8 @@ fi
+ if test "$SOLARIS_SUNPRO_CC"; then
+   PROFILE_GEN_CFLAGS="-xprofile=collect:$_objdir/$enable_application"
+   PROFILE_GEN_LDFLAGS="-xprofile=collect:$_objdir/$enable_application"
+-  PROFILE_USE_CFLAGS="-xprofile=use:$_objdir/$enable_application"
+-  PROFILE_USE_LDFLAGS="-xprofile=use:$_objdir/$enable_application"
++  PROFILE_USE_CFLAGS="-xtemp=$_objdir -xprofile=use:$_objdir/$enable_application"
++  PROFILE_USE_LDFLAGS="-xtemp=$_objdir -xprofile=use:$_objdir/$enable_application"
+ fi
+ 
+ 
+diff --git a/js/src/configure b/js/src/configure
+index 0e98daf..11bb34f 100755
+--- a/js/src/configure
++++ b/js/src/configure
+@@ -14560,10 +14560,15 @@ if test -n "$INTEL_CC"; then
+ fi
+ 
+ if test "$SOLARIS_SUNPRO_CC"; then
+-  PROFILE_GEN_CFLAGS="-xprofile=collect:$_objdir/$enable_application"
+-  PROFILE_GEN_LDFLAGS="-xprofile=collect:$_objdir/$enable_application"
+-  PROFILE_USE_CFLAGS="-xprofile=use:$_objdir/$enable_application"
+-  PROFILE_USE_LDFLAGS="-xprofile=use:$_objdir/$enable_application"
++  PROFILE_GEN_CFLAGS="-xprofile=collect:$_objdir/../../$enable_application"
++  PROFILE_GEN_LDFLAGS="-xprofile=collect:$_objdir/../../$enable_application"
++  if test "$CPU_ARCH" = "sparc"; then
++    PROFILE_USE_CFLAGS="-xtemp=$_objdir -xprofile=use:$_objdir/../../$enable_application"
++    PROFILE_USE_LDFLAGS="-xtemp=$_objdir -xprofile=use:$_objdir/../../$enable_application"
++  else
++    PROFILE_USE_CFLAGS=""
++    PROFILE_USE_LDFLAGS=""
++  fi
+ fi
+ 
+ 
+--- a/nsprpub/configure
++++ b/nsprpub/configure
+@@ -2789,11 +2789,13 @@
+ rm -f conftest*
+ echo "$ac_t""$result" 1>&6
+ 
++if test "$GNU_CC"; then
+ if test $result = "yes"; then
+    PROFILE_GEN_LDFLAGS="-fprofile-generate"
+    PROFILE_USE_CFLAGS="-fprofile-use -fprofile-correction -Wcoverage-mismatch -freorder-blocks-and-partition"
+    PROFILE_USE_LDFLAGS="-fprofile-use"
+ fi
++fi
+ 
+ CFLAGS="$_SAVE_CFLAGS"
+ 
+--- a/layout/style/Makefile.in
++++ b/layout/style/Makefile.in
+@@ -175,3 +175,9 @@
+ 	$(SYSINSTALL) $(IFLAGS1) $^ $(DESTDIR)$(mozappdir)/res
+ 
+ DEFINES += -D_IMPL_NS_LAYOUT
++
++Loader.o: Loader.cpp Makefile.in
++	$(REPORT_BUILD)
++	@$(MAKE_DEPS_AUTO_CXX)
++	$(CXX) -o $@ -c $(patsubst -xprofile=%,,$(COMPILE_CXXFLAGS)) $<
++
+--- a/extensions/spellcheck/hunspell/src/Makefile.in
++++ b/extensions/spellcheck/hunspell/src/Makefile.in
+@@ -38,6 +38,8 @@
+ srcdir          = @srcdir@
+ VPATH           = @srcdir@
+ 
++NO_PROFILE_GUIDED_OPTIMIZE = 1
++
+ include $(DEPTH)/config/autoconf.mk
+ 
+ MODULE           = hunspell
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/firefox6-27-methoidjit-sparc.diff	Mon Aug 15 02:22:00 2011 +0000
@@ -0,0 +1,1526 @@
+diff --git a/js/src/nanojit/NativeSparc.h b/js/src/nanojit/NativeSparc.h
+index 2a69caa..462ffc8 100644
+--- a/js/src/nanojit/NativeSparc.h
++++ b/js/src/nanojit/NativeSparc.h
+@@ -71,7 +71,7 @@
+ {
+     const int NJ_MAX_REGISTERS = 30; // L0 - L7, I0 - I5, F2 - F14
+ 
+-    const int LARGEST_UNDERRUN_PROT = 32;  // largest value passed to underrunProtect
++    const int LARGEST_UNDERRUN_PROT = 72;  // largest value passed to underrunProtect
+ 
+ #define NJ_MAX_STACK_ENTRY              8192
+ #define NJ_MAX_PARAMETERS               1
+@@ -203,16 +203,18 @@
+ #define DECLARE_PLATFORM_REGALLOC()
+ 
+ #define DECLARE_PLATFORM_ASSEMBLER()    \
++     friend class SafeUnderrunProtect; \
+      const static Register argRegs[6], retRegs[1]; \
+      void nativePageReset(); \
+      void nativePageSetup(); \
+      void underrunProtect(int bytes); \
+      bool hardenNopInsertion(const Config& /*c*/) { return false; } \
+      void asm_align_code(); \
+-     void asm_cmp(LIns *cond); \
+-     void asm_cmpd(LIns *cond); \
++     void asm_cmp(LIns* cond); \
++     void asm_cmpd(LIns* cond); \
+      NIns* asm_branchd(bool, LIns*, NIns*); \
+      void IMM32(int32_t i) { \
++         underrunProtect(4); \
+          --_nIns; \
+          *((int32_t*)_nIns) = i; \
+      } \
+@@ -294,16 +296,16 @@
+     void Format_4_5(Register rd, int32_t op3, int32_t cond, int32_t opf_cc, int32_t opf_low, Register rs2) { \
+         Format_3A(2, rd, op3, (cond & 0xF) << 14 | (opf_cc & 0x7) << 11 | (opf_low & 0x3F) << 5 | _reg_(rs2)); \
+     } \
+-    void IntegerOperation(Register rs1, Register rs2, Register rd, int32_t op3, const char *opcode); \
+-    void IntegerOperationI(Register rs1, int32_t simm13, Register rd, int32_t op3, const char *opcode); \
+-    void FloatOperation(Register rs1, Register rs2, Register rd, int32_t op3, const char *opcode); \
+-    void Bicc(int32_t a, int32_t dsp22, int32_t cond, const char *opcode); \
+-    void FBfcc(int32_t a, int32_t dsp22, int32_t cond, const char *opcode); \
++    void IntegerOperation(Register rs1, Register rs2, Register rd, int32_t op3, const char* opcode); \
++    void IntegerOperationI(Register rs1, int32_t simm13, Register rd, int32_t op3, const char* opcode); \
++    void FloatOperation(Register rs1, Register rs2, Register rd, int32_t op3, const char* opcode); \
++    void Bicc(int32_t a, int32_t dsp22, int32_t cond, const char* opcode); \
++    void FBfcc(int32_t a, int32_t dsp22, int32_t cond, const char* opcode); \
+     void LoadOperation(Register rs1, Register rs2, Register rd, int32_t op3, const char* opcode); \
+     void LoadOperationI(Register rs1, int32_t simm13, Register rd, int32_t op3, const char* opcode); \
+-    void MOVcc(Register rs, int32_t cc2, int32_t cc1, int32_t cc0, Register rd, int32_t cond, const char *opcode); \
+-    void MOVccI(int32_t simm11, int32_t cc2, int32_t cc1, int32_t cc0, Register rd, int32_t cond, const char *opcode); \
+-    void FMOVDcc(Register rs, int32_t opt_cc, Register rd, int32_t cond, const char *opcode); \
++    void MOVcc(Register rs, int32_t cc2, int32_t cc1, int32_t cc0, Register rd, int32_t cond, const char* opcode); \
++    void MOVccI(int32_t simm11, int32_t cc2, int32_t cc1, int32_t cc0, Register rd, int32_t cond, const char* opcode); \
++    void FMOVDcc(Register rs, int32_t opt_cc, Register rd, int32_t cond, const char* opcode); \
+     void ShiftOperation(Register rs1, Register rs2, Register rd, int32_t op3, const char* opcode); \
+     void ShiftOperationI(Register rs1, int32_t shcnt32, Register rd, int32_t op3, const char* opcode); \
+     void Store(Register rd, Register rs1, Register rs2, int32_t op3, const char* opcode); \
+@@ -442,14 +444,13 @@
+     void STB(Register rd, Register rs1, Register rs2); \
+     void STBI(Register rd, int32_t simm13, Register rs1); \
+     void STB32(Register rd, int32_t immI, Register rs1); \
+-    bool isIMM13(int32_t imm) { return (imm) <= 0xfff && (imm) >= -0x1000; } \
+-    bool isIMM19(int32_t imm) { return (imm) <= 0x3ffff && (imm) >= -0x40000; } \
+-    bool isIMM22(int32_t imm) { return (imm) <= 0x1fffff && (imm) >= -0x200000; } \
+-    void JMP_long_nocheck(int32_t t); \
++    static bool isIMM13(int32_t imm) { return (imm) <= 0xfff && (imm) >= -0x1000; } \
++    static bool isIMM19(int32_t imm) { return (imm) <= 0x3ffff && (imm) >= -0x40000; } \
++    static bool isIMM22(int32_t imm) { return (imm) <= 0x1fffff && (imm) >= -0x200000; } \
+     void JMP_long(int32_t t); \
+     void JMP_long_placeholder(); \
+-    int32_t JCC(void *t); \
+-    void JMP(void *t); \
++    int32_t JCC(void* t); \
++    void JMP(void* t); \
+     void MR(Register rd, Register rs);
+ }
+ #endif // __nanojit_NativeSparc__
+--- a/js/src/jsapi.cpp	2011-06-22 22:05:28.108252350 +0800
++++ b/js/src/jsapi.cpp	2011-06-22 22:06:13.458823300 +0800
+@@ -2763,6 +2763,12 @@
+ JS_PUBLIC_API(void)
+ JS_SetNativeStackQuota(JSContext *cx, size_t stackSize)
+ {
++#ifdef JS_CPU_SPARC
++    stackSize = stackSize * 8; // more stack is required on SPARC
++#else
++    // stackSize = stackSize * 2; // PGO needs more stack, why?
++#endif
++
+ #ifdef JS_THREADSAFE
+     JS_ASSERT(cx->thread());
+ #endif
+diff --git a/js/src/nanojit/NativeSparc.cpp b/js/src/nanojit/NativeSparc.cpp
+index 029a22a..a73be3d 100644
+--- a/js/src/nanojit/NativeSparc.cpp
++++ b/js/src/nanojit/NativeSparc.cpp
+@@ -47,9 +47,33 @@
+ namespace nanojit
+ {
+ #ifdef FEATURE_NANOJIT
++    class SafeUnderrunProtect
++    {
++        public:
++            SafeUnderrunProtect(Assembler* assembler, int n)
++            {
++                _nprotect = n;
++                _assembler = assembler;
++                _assembler->underrunProtect(n);
++                _priorIns = _assembler->_nIns;
++                _priorStart = _assembler->codeStart;
++            };
+ 
++            ~SafeUnderrunProtect()
++            {
++                NanoAssert(_priorStart == _assembler->codeStart);
++                NanoAssert((intptr_t)_priorIns - (intptr_t)_assembler->_nIns <= _nprotect);
++            };
++
++        private:
++            int _nprotect;
++            Assembler* _assembler;
++            NIns* _priorIns;
++            NIns* _priorStart;
++    };
++
+ #ifdef NJ_VERBOSE
+-    const char *regNames[] = {
++    const char* regNames[] = {
+         "%g0", "%g1", "%g2", "%g3", "%g4", "%g5", "%g6", "%g7",
+         "%o0", "%o1", "%o2", "%o3", "%o4", "%o5", "%sp", "%o7",
+         "%l0", "%l1", "%l2", "%l3", "%l4", "%l5", "%l6", "%l7",
+@@ -79,13 +103,13 @@
+     }
+ 
+     inline void Assembler::IntegerOperation
+-        (Register rs1, Register rs2, Register rd, int32_t op3, const char *opcode) {
++        (Register rs1, Register rs2, Register rd, int32_t op3, const char* opcode) {
+         Format_3_1(2, rd, op3, rs1, 0, rs2);
+         asm_output("%s %s, %s, %s", opcode, gpn(rs1), gpn(rs2), gpn(rd));
+     }
+ 
+     inline void Assembler::IntegerOperationI
+-        (Register rs1, int32_t simm13, Register rd, int32_t op3, const char *opcode) {
++        (Register rs1, int32_t simm13, Register rd, int32_t op3, const char* opcode) {
+         Format_3_1I(2, rd, op3, rs1, simm13);
+         asm_output("%s %s, %d, %s", opcode, gpn(rs1), simm13, gpn(rd));
+     }
+@@ -127,9 +151,9 @@
+         IntegerOperation(rs1, rs2, rd, 0x3, "xor");
+     }
+ 
+-    inline void Assembler::Bicc(int32_t a, int32_t dsp22, int32_t cond, const char *opcode) {
++    inline void Assembler::Bicc(int32_t a, int32_t dsp22, int32_t cond, const char* opcode) {
+         Format_2_2(a, cond, 0x2, dsp22);
+-        asm_output("%s 0x%x", opcode, _nIns + dsp22 - 1);
++        asm_output("%s 0x%x", opcode, _nIns + dsp22);
+     }
+ 
+     inline void Assembler::BA  (int32_t a, int32_t dsp22) { Bicc(a, dsp22, 0x8, "ba");   }
+@@ -156,7 +180,7 @@
+         asm_output("faddd %s, %s, %s", gpn(rs1), gpn(rs2), gpn(rd));
+     }
+ 
+-    inline void Assembler::FBfcc(int32_t a, int32_t dsp22, int32_t cond, const char *opcode) {
++    inline void Assembler::FBfcc(int32_t a, int32_t dsp22, int32_t cond, const char* opcode) {
+         Format_2_2(a, cond, 0x6, dsp22);
+         asm_output("%s 0x%x", opcode, _nIns + dsp22 - 1);
+     }
+@@ -179,7 +203,7 @@
+     }
+ 
+     inline void Assembler::FloatOperation
+-        (Register rs1, Register rs2, Register rd, int32_t opf, const char *opcode) {
++        (Register rs1, Register rs2, Register rd, int32_t opf, const char* opcode) {
+         Format_3_8(2, rd, 0x34, rs1, opf, rs2);
+         if (rs1 != G0) {
+           asm_output("%s %s, %s, %s", opcode, gpn(rs1), gpn(rs2), gpn(rd));
+@@ -347,13 +371,13 @@
+     }
+ 
+     inline void Assembler::MOVcc
+-        (Register rs, int32_t cc2, int32_t cc1, int32_t cc0, Register rd, int32_t cond, const char *opcode) {
++        (Register rs, int32_t cc2, int32_t cc1, int32_t cc0, Register rd, int32_t cond, const char* opcode) {
+         Format_4_2(rd, 0x2c, cc2, cond, cc1, cc0, rs);
+         asm_output("%s %s, %s", opcode, gpn(rs), gpn(rd));
+     }
+ 
+     inline void Assembler::MOVccI
+-        (int32_t simm11, int32_t cc2, int32_t cc1, int32_t cc0, Register rd, int32_t cond, const char *opcode) {
++        (int32_t simm11, int32_t cc2, int32_t cc1, int32_t cc0, Register rd, int32_t cond, const char* opcode) {
+         Format_4_2I(rd, 0x2c, cc2, cond, cc1, cc0, simm11);
+         asm_output("%s 0x%x, %s", opcode, simm11, gpn(rd));
+     }
+@@ -386,7 +410,7 @@
+     inline void Assembler::MOVFGI (int32_t simm11, Register rd) { MOVccI(simm11, 0, 0, 0, rd, 0x6, "movfg");  }
+     inline void Assembler::MOVFGEI(int32_t simm11, Register rd) { MOVccI(simm11, 0, 0, 0, rd, 0xb, "movfge"); }
+ 
+-    inline void Assembler::FMOVDcc(Register rs, int32_t opt_cc, Register rd, int32_t cond, const char *opcode) {
++    inline void Assembler::FMOVDcc(Register rs, int32_t opt_cc, Register rd, int32_t cond, const char* opcode) {
+         Format_4_5(rd, 0x35, cond, opt_cc, 0x2, rs);
+         asm_output("%s %s, %s", opcode, gpn(rs), gpn(rd));
+     }
+@@ -556,7 +580,19 @@
+     }
+ 
+     // general Assemble
+-    inline void Assembler::JMP_long_nocheck(int32_t t) {
++    inline void Assembler::JMP_long(int32_t t) {
++        SafeUnderrunProtect protect(this, 16);
++    /*    if (t) {
++            int32_t tt = ((intptr_t)t - (intptr_t)_nIns + 16) >> 2;
++            if (isIMM22(tt)) {
++                NOP();
++                NOP();
++                NOP();
++                BA(0,tt);
++                return;
++            }
++        }
++*/
+         NOP();
+         JMPL(G0, G2, G0);
+         ORI(G2, t & 0x3FF, G2);
+@@ -563,17 +599,12 @@
+         SETHI(t, G2);
+     }
+ 
+-    inline void Assembler::JMP_long(int32_t t) {
+-        underrunProtect(16);
+-        JMP_long_nocheck(t);
+-    }
+-
+     inline void Assembler::JMP_long_placeholder() {
+         JMP_long(0);
+     }
+ 
+-    inline int32_t Assembler::JCC(void *t) {
+-        underrunProtect(32);
++    inline int32_t Assembler::JCC(void* t) {
++        SafeUnderrunProtect protect(this, 32);
+         int32_t tt = ((intptr_t)t - (intptr_t)_nIns + 8) >> 2;
+         if( !(isIMM22(tt)) ) {
+             NOP();
+@@ -587,7 +618,7 @@
+         return tt;
+     }
+ 
+-    void Assembler::JMP(void *t) {
++    void Assembler::JMP(void* t) {
+         if (!t) {
+             JMP_long_placeholder();
+         } else {
+@@ -597,7 +628,6 @@
+     }
+ 
+     void Assembler::MR(Register rd, Register rs) {
+-        underrunProtect(4);
+         ORI(rs, 0, rd);
+     }
+ 
+@@ -612,7 +642,7 @@
+         /**
+          * Prologue
+          */
+-        underrunProtect(16);
++        SafeUnderrunProtect protect(this, 28);
+         uint32_t stackNeeded = STACK_GRANULARITY * _activation.stackSlotsNeeded();
+         uint32_t frameSize = stackNeeded + kcalleeAreaSize + kLinkageAreaSize;
+         frameSize = BIT_ROUND_UP(frameSize, 8);
+@@ -630,7 +660,7 @@
+             outputf("        0x%x:",_nIns);
+             outputf("        patch entry:");
+         })
+-        NIns *patchEntry = _nIns;
++        NIns* patchEntry = _nIns;
+ 
+         // The frame size in SAVE is faked. We will still re-caculate SP later.
+         // We can use 0 here but it is not good for debuggers.
+@@ -642,7 +672,8 @@
+         return patchEntry;
+     }
+ 
+-    void Assembler::asm_align_code() {
++    void Assembler::asm_align_code()
++    {
+         while(uintptr_t(_nIns) & 15) {
+             NOP();
+         }
+@@ -651,30 +682,27 @@
+     void Assembler::nFragExit(LIns* guard)
+     {
+         SideExit* exit = guard->record()->exit;
+-        Fragment *frag = exit->target;
+-        GuardRecord *lr;
+-        if (frag && frag->fragEntry)
+-            {
+-                JMP(frag->fragEntry);
+-                lr = 0;
+-            }
+-        else
+-            {
+-                // Target doesn't exit yet. Emit jump to epilog, and set up to patch later.
+-                if (!_epilogue)
+-                    _epilogue = genEpilogue();
+-                lr = guard->record();
+-                JMP_long((intptr_t)_epilogue);
+-                lr->jmp = _nIns;
+-            }
++        Fragment* frag = exit->target;
++        GuardRecord* lr;
++        if (frag && frag->fragEntry) {
++            JMP(frag->fragEntry);
++            lr = 0;
++        } else {
++            // Target doesn't exit yet. Emit jump to epilog, and set up to patch later.
++            if (!_epilogue)
++                _epilogue = genEpilogue();
++            lr = guard->record();
++            JMP_long((intptr_t)_epilogue);
++            lr->jmp = _nIns;
++        }
+ 
+         // return value is GuardRecord*
+         SET32(int(lr), O0);
+     }
+ 
+-    NIns *Assembler::genEpilogue()
++    NIns* Assembler::genEpilogue()
+     {
+-        underrunProtect(12);
++        SafeUnderrunProtect protect(this, 12);
+         RESTORE(G0, G0, G0); //restore
+         JMPLI(I7, 8, G0); //ret
+         ORI(O0, 0, I0);
+@@ -684,19 +712,15 @@
+     void Assembler::asm_call(LIns* ins)
+     {
+         if (!ins->isop(LIR_callv)) {
+-            Register retReg = ( ins->isop(LIR_calld) ? F0 : retRegs[0] );
+-            deprecated_prepResultReg(ins, rmask(retReg));
++            Register retReg = (ins->isop(LIR_calld) ? F0 : retRegs[0]);
++            prepareResultReg(ins, rmask(retReg));
++            evictScratchRegsExcept(rmask(retReg));
++        } else {
++            evictScratchRegsExcept(0);
+         }
+ 
+-        // Do this after we've handled the call result, so we don't
+-        // force the call result to be spilled unnecessarily.
+-        evictScratchRegsExcept(0);
+-
+         const CallInfo* ci = ins->callInfo();
+ 
+-        underrunProtect(8);
+-        NOP();
+-
+         ArgType argTypes[MAXARGS];
+         uint32_t argc = ci->getArgTypes(argTypes);
+ 
+@@ -704,53 +728,59 @@
+                    ins->isop(LIR_calld));
+         verbose_only(if (_logc->lcbits & LC_Native)
+                      outputf("        0x%x:", _nIns);
+-                     )
++                    )
+         bool indirect = ci->isIndirect();
+-        if (!indirect) {
+-            CALL(ci);
++
++        {
++            SafeUnderrunProtect protect(this, 8);
++            NOP();
++            if (!indirect) {
++                CALL(ci);
++            }
++            else {
++                argc--;
++                Register r = findSpecificRegFor(ins->arg(argc), I0);
++                JMPL(G0, I0, O7);
++            }
+         }
+-        else {
+-            argc--;
+-            Register r = findSpecificRegFor(ins->arg(argc), I0);
+-            JMPL(G0, I0, O7);
+-        }
+ 
++        freeResourcesOf(ins);
++
+         Register GPRIndex = O0;
+         uint32_t offset = kLinkageAreaSize; // start of parameters stack postion.
+ 
+-        for(int i=0; i<argc; i++)
+-            {
+-                uint32_t j = argc-i-1;
+-                ArgType ty = argTypes[j];
+-                if (ty == ARGTYPE_D) {
+-                    Register r = findRegFor(ins->arg(j), FpRegs);
++        for (int i = 0; i < argc; i++) {
++            uint32_t j = argc-i-1;
++            ArgType ty = argTypes[j];
++            if (ty == ARGTYPE_D) {
++                Register r = findRegFor(ins->arg(j), FpRegs);
+ 
+-                    underrunProtect(48);
+-                    // We might be calling a varargs function.
+-                    // So, make sure the GPR's are also loaded with
+-                    // the value, or the stack contains it.
+-                    if (GPRIndex <= O5) {
+-                        LDSW32(SP, offset, GPRIndex);
+-                    }
+-                    GPRIndex = GPRIndex + 1;
+-                    if (GPRIndex <= O5) {
+-                        LDSW32(SP, offset+4, GPRIndex);
+-                    }
+-                    GPRIndex = GPRIndex + 1;
+-                    STDF32(r, offset, SP);
+-                    offset += 8;
++                SafeUnderrunProtect protect(this, 48);
++                // We might be calling a varargs function.
++                // So, make sure the GPR's are also loaded with
++                // the value, or the stack contains it.
++                if (GPRIndex <= O5) {
++                    LDSW32(SP, offset, GPRIndex);
++                }
++                GPRIndex = GPRIndex + 1;
++                if (GPRIndex <= O5) {
++                    LDSW32(SP, offset+4, GPRIndex);
++                }
++                GPRIndex = GPRIndex + 1;
++                STDF32(r, offset, SP);
++                offset += 8;
++            } else {
++                if (GPRIndex > O5) {
++                    SafeUnderrunProtect protect(this, 12);
++                    Register r = findRegFor(ins->arg(j), GpRegs);
++                    STW32(r, offset, SP);
+                 } else {
+-                    if (GPRIndex > O5) {
+-                        underrunProtect(12);
+-                        Register r = findRegFor(ins->arg(j), GpRegs);
+-                        STW32(r, offset, SP);
+-                    } else {
+-                        Register r = findSpecificRegFor(ins->arg(j), GPRIndex);
+-                    }
+-                    GPRIndex = GPRIndex + 1;
+-                    offset += 4;
++                    Register r = findSpecificRegFor(ins->arg(j), GPRIndex);
+                 }
++                GPRIndex = GPRIndex + 1;
++                offset += 4;
+             }
++        }
+     }
+ 
+     Register Assembler::nRegisterAllocFromSet(RegisterMask set)
+@@ -771,10 +801,16 @@
+ 
+     void Assembler::nPatchBranch(NIns* branch, NIns* location)
+     {
+-        *(uint32_t*)&branch[0] &= 0xFFC00000;
+-        *(uint32_t*)&branch[0] |= ((intptr_t)location >> 10) & 0x3FFFFF;
+-        *(uint32_t*)&branch[1] &= 0xFFFFFC00;
+-        *(uint32_t*)&branch[1] |= (intptr_t)location & 0x3FF;
++        intptr_t addr_diff = ((intptr_t)location - (intptr_t)branch) >> 2;
++        if ( !isIMM22(addr_diff)) {
++            *(uint32_t*)&branch[0] = 0x05000000 | ((intptr_t)location >> 10) & 0x3FFFFF; // sethi ..., %g2
++            *(uint32_t*)&branch[1] = 0x8410a000 | (intptr_t)location & 0x3FF; // bset ..., %g2
++            *(uint32_t*)&branch[2] = 0x81c00002; // jmp %g2
++        } else {
++            *(uint32_t*)&branch[0] = 0x10800000 | (addr_diff & 0x3FFFFF); // ba
++            *(uint32_t*)&branch[1] = 0x01000000; // nop
++            *(uint32_t*)&branch[2] = 0x01000000; // nop
++        }
+     }
+ 
+     RegisterMask Assembler::nHint(LIns* ins)
+@@ -791,10 +827,10 @@
+ 
+     void Assembler::asm_restore(LIns* i, Register r)
+     {
+-        underrunProtect(24);
++        SafeUnderrunProtect protect(this, 24);
+         if (i->isop(LIR_allocp)) {
+             ADD(FP, L2, r);
+-            int32_t d = deprecated_disp(i);
++            int32_t d = arDisp(i);
+             SET32(d, L2);
+         }
+         else if (i->isImmI()) {
+@@ -810,7 +846,7 @@
+         }
+     }
+ 
+-    void Assembler::asm_store32(LOpcode op, LIns *value, int dr, LIns *base)
++    void Assembler::asm_store32(LOpcode op, LIns* value, int dr, LIns* base)
+     {
+         switch (op) {
+             case LIR_sti:
+@@ -823,53 +859,38 @@
+                 return;
+         }
+ 
+-        underrunProtect(20);
+-        if (value->isImmI())
+-            {
+-                Register rb = getBaseReg(base, dr, GpRegs);
+-                int c = value->immI();
+-                switch (op) {
+-                case LIR_sti:
+-                    STW32(L2, dr, rb);
+-                    break;
+-                case LIR_sti2c:
+-                    STB32(L2, dr, rb);
+-                    break;
+-                case LIR_sti2s:
+-                    STH32(L2, dr, rb);
+-                    break;
+-                }
+-                SET32(c, L2);
++        SafeUnderrunProtect protect(this, 20);
++        if (value->isImmI()) {
++            Register rb = getBaseReg(base, dr, GpRegs);
++            int c = value->immI();
++            switch (op) {
++                case LIR_sti:   STW32(L2, dr, rb); break;
++                case LIR_sti2c: STB32(L2, dr, rb); break;
++                case LIR_sti2s: STH32(L2, dr, rb); break;
+             }
+-        else
+-            {
+-                // make sure what is in a register
+-                Register ra, rb;
+-                if (base->isImmI()) {
+-                    // absolute address
+-                    dr += base->immI();
+-                    ra = findRegFor(value, GpRegs);
+-                    rb = G0;
+-                } else {
+-                    getBaseReg2(GpRegs, value, ra, GpRegs, base, rb, dr);
+-                }
+-                switch (op) {
+-                case LIR_sti:
+-                    STW32(ra, dr, rb);
+-                    break;
+-                case LIR_sti2c:
+-                    STB32(ra, dr, rb);
+-                    break;
+-                case LIR_sti2s:
+-                    STH32(ra, dr, rb);
+-                    break;
+-                }
++            SET32(c, L2);
++        } else {
++            // make sure what is in a register
++            Register ra, rb;
++            if (base->isImmI()) {
++                // absolute address
++                dr += base->immI();
++                ra = findRegFor(value, GpRegs);
++                rb = G0;
++            } else {
++                getBaseReg2(GpRegs, value, ra, GpRegs, base, rb, dr);
+             }
++            switch (op) {
++                case LIR_sti:   STW32(ra, dr, rb); break;
++                case LIR_sti2c: STB32(ra, dr, rb); break;
++                case LIR_sti2s: STH32(ra, dr, rb); break;
++            }
++        }
+     }
+ 
+     void Assembler::asm_spill(Register rr, int d, bool quad)
+     {
+-        underrunProtect(24);
++        SafeUnderrunProtect protect(this, 24);
+         (void)quad;
+         NanoAssert(d);
+         if (rmask(rr) & FpRegs) {
+@@ -891,7 +912,7 @@
+                 return;
+         }
+ 
+-        underrunProtect(48);
++        SafeUnderrunProtect protect(this, 48);
+         LIns* base = ins->oprnd1();
+         int db = ins->disp();
+         Register rb = getBaseReg(base, db, GpRegs);
+@@ -936,7 +957,7 @@
+                 return;
+         }
+ 
+-        underrunProtect(48);
++        SafeUnderrunProtect protect(this, 48);
+         Register rb = getBaseReg(base, dr, GpRegs);
+         if (op == LIR_std2f) {
+             Register rv = ( !value->isInReg()
+@@ -948,32 +969,30 @@
+             return;
+         }
+ 
+-        if (value->isImmD())
+-            {
+-                // if a constant 64-bit value just store it now rather than
+-                // generating a pointless store/load/store sequence
+-                STW32(L2, dr+4, rb);
+-                SET32(value->immDlo(), L2);
+-                STW32(L2, dr, rb);
+-                SET32(value->immDhi(), L2);
+-                return;
+-            }
++        if (value->isImmD()) {
++            // if a constant 64-bit value just store it now rather than
++            // generating a pointless store/load/store sequence
++            STW32(L2, dr+4, rb);
++            SET32(value->immDlo(), L2);
++            STW32(L2, dr, rb);
++            SET32(value->immDhi(), L2);
++            return;
++        }
+ 
+-        if (value->isop(LIR_ldd))
+-            {
+-                // value is 64bit struct or int64_t, or maybe a double.
+-                // it may be live in an FPU reg.  Either way, don't
+-                // put it in an FPU reg just to load & store it.
++        if (value->isop(LIR_ldd)) {
++            // value is 64bit struct or int64_t, or maybe a double.
++            // it may be live in an FPU reg.  Either way, don't
++            // put it in an FPU reg just to load & store it.
+ 
+-                // a) if we know it's not a double, this is right.
+-                // b) if we guarded that its a double, this store could be on
+-                // the side exit, copying a non-double.
+-                // c) maybe its a double just being stored.  oh well.
++            // a) if we know it's not a double, this is right.
++            // b) if we guarded that its a double, this store could be on
++            // the side exit, copying a non-double.
++            // c) maybe its a double just being stored.  oh well.
+ 
+-                int da = findMemFor(value);
+-                asm_mmq(rb, dr, FP, da);
+-                return;
+-            }
++            int da = findMemFor(value);
++             asm_mmq(rb, dr, FP, da);
++             return;
++        }
+ 
+         // if value already in a reg, use that, otherwise
+         // get it into FPU regs.
+@@ -1004,66 +1023,56 @@
+         NIns* at = 0;
+         LOpcode condop = cond->opcode();
+         NanoAssert(cond->isCmp());
+-        if (isCmpDOpcode(condop))
+-            {
+-                return Branches(asm_branchd(branchOnFalse, cond, targ));
+-            }
++        if (isCmpDOpcode(condop)) {
++            return Branches(asm_branchd(branchOnFalse, cond, targ));
++        }
+ 
+-        underrunProtect(32);
+-        intptr_t tt = ((intptr_t)targ - (intptr_t)_nIns + 8) >> 2;
+-        // !targ means that it needs patch.
+-        if( !(isIMM22((int32_t)tt)) || !targ ) {
+-            JMP_long_nocheck((intptr_t)targ);
+-            at = _nIns;
++        {
++            SafeUnderrunProtect protect(this, 32);
++            intptr_t tt = ((intptr_t)targ - (intptr_t)_nIns + 8) >> 2;
++            // !targ means that it needs patch.
++            if( !(isIMM22((int32_t)tt)) || !targ ) {
++                JMP_long((intptr_t)targ);
++                at = _nIns;
++                NOP();
++                BA(0, 5);
++                tt = 4;
++            }
+             NOP();
+-            BA(0, 5);
+-            tt = 4;
+-        }
+-        NOP();
+ 
+-        // produce the branch
+-        if (branchOnFalse)
+-            {
+-                if (condop == LIR_eqi)
+-                    BNE(0, tt);
+-                else if (condop == LIR_lti)
+-                    BGE(0, tt);
+-                else if (condop == LIR_lei)
+-                    BG(0, tt);
+-                else if (condop == LIR_gti)
+-                    BLE(0, tt);
+-                else if (condop == LIR_gei)
+-                    BL(0, tt);
+-                else if (condop == LIR_ltui)
+-                    BCC(0, tt);
+-                else if (condop == LIR_leui)
+-                    BGU(0, tt);
+-                else if (condop == LIR_gtui)
+-                    BLEU(0, tt);
+-                else //if (condop == LIR_geui)
+-                    BCS(0, tt);
++            // produce the branch
++            if (branchOnFalse) {
++                switch (condop) {
++                    case LIR_eqi : BNE (0, tt); break;
++                    case LIR_lti : BGE (0, tt); break;
++                    case LIR_lei : BG  (0, tt); break;
++                    case LIR_gti : BLE (0, tt); break;
++                    case LIR_gei : BL  (0, tt); break;
++                    case LIR_ltui: BCC (0, tt); break;
++                    case LIR_leui: BGU (0, tt); break;
++                    case LIR_gtui: BLEU(0, tt); break;
++                    case LIR_geui: BCS (0, tt); break;
++                    default:
++                        NanoAssertMsg(0, "asm_branch should never receive this cond opcode");
++                        return;
++                }
++            } else {// op == LIR_xt
++                switch (condop) {
++                    case LIR_eqi : BE  (0, tt); break;
++                    case LIR_lti : BL  (0, tt); break;
++                    case LIR_lei : BLE (0, tt); break;
++                    case LIR_gti : BG  (0, tt); break;
++                    case LIR_gei : BGE (0, tt); break;
++                    case LIR_ltui: BCS (0, tt); break;
++                    case LIR_leui: BLEU(0, tt); break;
++                    case LIR_gtui: BGU (0, tt); break;
++                    case LIR_geui: BCC (0, tt); break;
++                    default:
++                        NanoAssertMsg(0, "asm_branch should never receive this cond opcode");
++                        return;
++                }
+             }
+-        else // op == LIR_xt
+-            {
+-                if (condop == LIR_eqi)
+-                    BE(0, tt);
+-                else if (condop == LIR_lti)
+-                    BL(0, tt);
+-                else if (condop == LIR_lei)
+-                    BLE(0, tt);
+-                else if (condop == LIR_gti)
+-                    BG(0, tt);
+-                else if (condop == LIR_gei)
+-                    BGE(0, tt);
+-                else if (condop == LIR_ltui)
+-                    BCS(0, tt);
+-                else if (condop == LIR_leui)
+-                    BLEU(0, tt);
+-                else if (condop == LIR_gtui)
+-                    BGU(0, tt);
+-                else //if (condop == LIR_geui)
+-                    BCC(0, tt);
+-            }
++        }
+         asm_cmp(cond);
+         return Branches(at);
+     }
+@@ -1071,11 +1080,11 @@
+     NIns* Assembler::asm_branch_ov(LOpcode op, NIns* targ)
+     {
+         NIns* at = 0;
+-        underrunProtect(32);
++        SafeUnderrunProtect protect(this, 32);
+         intptr_t tt = ((intptr_t)targ - (intptr_t)_nIns + 8) >> 2;
+         // !targ means that it needs patch.
+-        if( !(isIMM22((int32_t)tt)) || !targ ) {
+-            JMP_long_nocheck((intptr_t)targ);
++        if (!(isIMM22((int32_t)tt)) || !targ) {
++            JMP_long((intptr_t)targ);
+             at = _nIns;
+             NOP();
+             BA(0, 5);
+@@ -1083,7 +1092,7 @@
+         }
+         NOP();
+ 
+-        if( op == LIR_mulxovi || op == LIR_muljovi )
++        if (op == LIR_mulxovi || op == LIR_muljovi)
+             BNE(0, tt);
+         else
+             BVS(0, tt);
+@@ -1090,10 +1099,8 @@
+         return at;
+     }
+ 
+-    void Assembler::asm_cmp(LIns *cond)
++    void Assembler::asm_cmp(LIns* cond)
+     {
+-        underrunProtect(12);
+-
+         LIns* lhs = cond->oprnd1();
+         LIns* rhs = cond->oprnd2();
+ 
+@@ -1100,182 +1107,205 @@
+         NanoAssert(lhs->isI() && rhs->isI());
+ 
+         // ready to issue the compare
+-        if (rhs->isImmI())
+-            {
+-                int c = rhs->immI();
+-                Register r = findRegFor(lhs, GpRegs);
+-                if (c == 0 && cond->isop(LIR_eqi)) {
+-                    ANDCC(r, r, G0);
+-                }
+-                else {
+-                    SUBCC(r, L2, G0);
+-                    SET32(c, L2);
+-                }
++        if (rhs->isImmI()) {
++            int c = rhs->immI();
++            Register r = findRegFor(lhs, GpRegs);
++            SafeUnderrunProtect protect(this, 12);
++            if (c == 0 && cond->isop(LIR_eqi)) {
++                ANDCC(r, r, G0);
++            } else {
++                SUBCC(r, L2, G0);
++                SET32(c, L2);
+             }
+-        else
+-            {
+-                Register ra, rb;
+-                findRegFor2(GpRegs, lhs, ra, GpRegs, rhs, rb);
+-                SUBCC(ra, rb, G0);
+-            }
++        } else {
++            Register ra, rb;
++            findRegFor2(GpRegs, lhs, ra, GpRegs, rhs, rb);
++            SUBCC(ra, rb, G0);
++        }
+     }
+ 
+     void Assembler::asm_condd(LIns* ins)
+     {
+         // only want certain regs
+-        Register r = deprecated_prepResultReg(ins, AllowableFlagRegs);
+-        underrunProtect(8);
++        Register r = prepareResultReg(ins, AllowableFlagRegs);
++        SafeUnderrunProtect protect(this, 12);
+         LOpcode condop = ins->opcode();
+         NanoAssert(isCmpDOpcode(condop));
+-        if (condop == LIR_eqd)
+-            MOVFEI(1, r);
+-        else if (condop == LIR_led)
+-            MOVFLEI(1, r);
+-        else if (condop == LIR_ltd)
+-            MOVFLI(1, r);
+-        else if (condop == LIR_ged)
+-            MOVFGEI(1, r);
+-        else // if (condop == LIR_gtd)
+-            MOVFGI(1, r);
++        switch (condop) {
++            case LIR_eqd: MOVFEI (1, r); break;
++            case LIR_led: MOVFLEI(1, r); break;
++            case LIR_ltd: MOVFLI (1, r); break;
++            case LIR_ged: MOVFGEI(1, r); break;
++            case LIR_gtd: MOVFGI (1, r); break;
++            default:
++                NanoAssertMsg(0, "asm_condd should never receive this cond opcode");
++                return;
++        }
+         ORI(G0, 0, r);
++        freeResourcesOf(ins);
+         asm_cmpd(ins);
+     }
+ 
+     void Assembler::asm_cond(LIns* ins)
+     {
+-        underrunProtect(8);
+         // only want certain regs
+-        LOpcode op = ins->opcode();
+-        Register r = deprecated_prepResultReg(ins, AllowableFlagRegs);
++        LOpcode condop = ins->opcode();
++        Register r = prepareResultReg(ins, AllowableFlagRegs);
++        SafeUnderrunProtect protect(this, 20);
+ 
+-        if (op == LIR_eqi)
+-            MOVEI(1, r);
+-        else if (op == LIR_lti)
+-            MOVLI(1, r);
+-        else if (op == LIR_lei)
+-            MOVLEI(1, r);
+-        else if (op == LIR_gti)
+-            MOVGI(1, r);
+-        else if (op == LIR_gei)
+-            MOVGEI(1, r);
+-        else if (op == LIR_ltui)
+-            MOVCSI(1, r);
+-        else if (op == LIR_leui)
+-            MOVLEUI(1, r);
+-        else if (op == LIR_gtui)
+-            MOVGUI(1, r);
+-        else // if (op == LIR_geui)
+-            MOVCCI(1, r);
++        switch (condop) {
++            case LIR_eqi : MOVEI  (1, r); break;
++            case LIR_lti : MOVLI  (1, r); break;
++            case LIR_lei : MOVLEI (1, r); break;
++            case LIR_gti : MOVGI  (1, r); break;
++            case LIR_gei : MOVGEI (1, r); break;
++            case LIR_ltui: MOVCSI (1, r); break;
++            case LIR_leui: MOVLEUI(1, r); break;
++            case LIR_gtui: MOVGUI (1, r); break;
++            case LIR_geui: MOVCCI (1, r); break;
++            default:
++                NanoAssertMsg(0, "asm_cond should never receive this cond opcode");
++                return;
++        }
+         ORI(G0, 0, r);
++        freeResourcesOf(ins);
+         asm_cmp(ins);
+     }
+ 
+     void Assembler::asm_arith(LIns* ins)
+     {
+-        underrunProtect(28);
++        SafeUnderrunProtect protect(this, 28);
+         LOpcode op = ins->opcode();
+         LIns* lhs = ins->oprnd1();
+         LIns* rhs = ins->oprnd2();
+ 
+-        Register rb = deprecated_UnknownReg;
++        Register rb;
+         RegisterMask allow = GpRegs;
+         bool forceReg = (op == LIR_muli || op == LIR_mulxovi || op == LIR_muljovi || !rhs->isImmI());
+ 
+-        if (lhs != rhs && forceReg)
+-            {
+-                if ((rb = asm_binop_rhs_reg(ins)) == deprecated_UnknownReg) {
+-                    rb = findRegFor(rhs, allow);
+-                }
+-                allow &= ~rmask(rb);
+-            }
+-        else if ((op == LIR_addi || op == LIR_addxovi || op == LIR_addjovi) && lhs->isop(LIR_allocp) && rhs->isImmI()) {
++        if (lhs != rhs && forceReg) {
++            rb = findRegFor(rhs, allow);
++            allow &= ~rmask(rb);
++        } else if ((op == LIR_addi || op == LIR_addxovi || op == LIR_addjovi) && lhs->isop(LIR_allocp) && rhs->isImmI()) {
+             // add alloc+const, use lea
+-            Register rr = deprecated_prepResultReg(ins, allow);
++            Register rr = prepareResultReg(ins, allow);
+             int d = findMemFor(lhs) + rhs->immI();
++            SafeUnderrunProtect protect(this, 12);
+             ADD(FP, L2, rr);
+             SET32(d, L2);
++            freeResourcesOf(ins);
+             return;
+         }
+ 
+-        Register rr = deprecated_prepResultReg(ins, allow);
+-        // if this is last use of lhs in reg, we can re-use result reg
+-        // else, lhs already has a register assigned.
+-        Register ra = ( !lhs->isInReg()
+-                      ? findSpecificRegFor(lhs, rr)
+-                      : lhs->deprecated_getReg() );
++        Register rr = prepareResultReg(ins, allow);
+ 
+-        if (forceReg)
+-            {
+-                if (lhs == rhs)
+-                    rb = ra;
++        // If 'lhs' isn't in a register, it can be clobbered by 'ins'.
++        Register ra = lhs->isInReg() ? lhs->getReg() : rr;
+ 
+-                if (op == LIR_addi || op == LIR_addxovi || op == LIR_addjovi)
++        if (forceReg) {
++            if (lhs == rhs)
++                rb = ra;
++
++            switch (op) {
++                case LIR_addi:
++                case LIR_addxovi:
++                case LIR_addjovi:
+                     ADDCC(rr, rb, rr);
+-                else if (op == LIR_subi || op == LIR_subxovi || op == LIR_subjovi)
++                    break;
++                case LIR_subi:
++                case LIR_subxovi:
++                case LIR_subjovi:
+                     SUBCC(rr, rb, rr);
+-                else if (op == LIR_muli)
++                    break;
++                case LIR_muli:
+                     SMULCC(rr, rb, rr);
+-                else if (op == LIR_mulxovi || op == LIR_muljovi) {
++                    break;
++                case LIR_mulxovi:
++                case LIR_muljovi:
+                     SUBCC(L4, L6, L4);
+                     SRAI(rr, 31, L6);
+                     RDY(L4);
+                     SMULCC(rr, rb, rr);
+-                }
+-                else if (op == LIR_andi)
++                    break;
++                case LIR_andi:
+                     AND(rr, rb, rr);
+-                else if (op == LIR_ori)
++                    break;
++                case LIR_ori:
+                     OR(rr, rb, rr);
+-                else if (op == LIR_xori)
++                    break;
++                case LIR_xori:
+                     XOR(rr, rb, rr);
+-                else if (op == LIR_lshi)
++                    break;
++                case LIR_lshi:
+                     SLL(rr, rb, rr);
+-                else if (op == LIR_rshi)
++                    break;
++                case LIR_rshi:
+                     SRA(rr, rb, rr);
+-                else if (op == LIR_rshui)
++                    break;
++                case LIR_rshui:
+                     SRL(rr, rb, rr);
+-                else
++                    break;
++                default:
+                     NanoAssertMsg(0, "Unsupported");
++                    return;
+             }
+-        else
+-            {
+-                int c = rhs->immI();
+-                if (op == LIR_addi || op == LIR_addxovi || op == LIR_addjovi)
++        } else {
++            int c = rhs->immI();
++            switch (op) {
++                case LIR_addi:
++                case LIR_addxovi:
++                case LIR_addjovi:
+                     ADDCC(rr, L2, rr);
+-                else if (op == LIR_subi || op == LIR_subxovi || op == LIR_subjovi)
++                    break;
++                case LIR_subi:
++                case LIR_subxovi:
++                case LIR_subjovi:
+                     SUBCC(rr, L2, rr);
+-                else if (op == LIR_andi)
++                    break;
++                case LIR_andi:
+                     AND(rr, L2, rr);
+-                else if (op == LIR_ori)
++                    break;
++                case LIR_ori:
+                     OR(rr, L2, rr);
+-                else if (op == LIR_xori)
++                    break;
++                case LIR_xori:
+                     XOR(rr, L2, rr);
+-                else if (op == LIR_lshi)
++                    break;
++                case LIR_lshi:
+                     SLL(rr, L2, rr);
+-                else if (op == LIR_rshi)
++                    break;
++                case LIR_rshi:
+                     SRA(rr, L2, rr);
+-                else if (op == LIR_rshui)
++                    break;
++                case LIR_rshui:
+                     SRL(rr, L2, rr);
+-                else
++                    break;
++                default:
+                     NanoAssertMsg(0, "Unsupported");
+-                SET32(c, L2);
++                    return;
+             }
++            SET32(c, L2);
++        }
+ 
+-        if ( rr != ra )
++        if (rr != ra)
+             ORI(ra, 0, rr);
++
++        freeResourcesOf(ins);
++        if (!lhs->isInReg()) {
++            NanoAssert(ra == rr);
++            findSpecificRegForUnallocated(lhs, ra);
++        }
+     }
+ 
+     void Assembler::asm_neg_not(LIns* ins)
+     {
+-        underrunProtect(8);
+         LOpcode op = ins->opcode();
+-        Register rr = deprecated_prepResultReg(ins, GpRegs);
++        Register rr = prepareResultReg(ins, GpRegs);
+ 
++        SafeUnderrunProtect protect(this, 16);
+         LIns* lhs = ins->oprnd1();
+-        // if this is last use of lhs in reg, we can re-use result reg
+-        // else, lhs already has a register assigned.
+-        Register ra = ( !lhs->isInReg()
+-                      ? findSpecificRegFor(lhs, rr)
+-                      : lhs->deprecated_getReg() );
++        // If 'lhs' isn't in a register, it can be clobbered by 'ins'.
++        Register ra = lhs->isInReg() ? lhs->getReg() : rr;
+ 
+         if (op == LIR_noti)
+             ORN(G0, rr, rr);
+@@ -1282,43 +1312,44 @@
+         else
+             SUB(G0, rr, rr);
+ 
+-        if ( rr != ra )
++        if (rr != ra)
+             ORI(ra, 0, rr);
++
++        freeResourcesOf(ins);
++        if (!lhs->isInReg()) {
++            NanoAssert(ra == rr);
++            findSpecificRegForUnallocated(lhs, ra);
++        }
+     }
+ 
+     void Assembler::asm_load32(LIns* ins)
+     {
+-        underrunProtect(12);
+         LOpcode op = ins->opcode();
+         LIns* base = ins->oprnd1();
+         int d = ins->disp();
+-        Register rr = deprecated_prepResultReg(ins, GpRegs);
++        Register rr = prepareResultReg(ins, GpRegs);
+         Register ra = getBaseReg(base, d, GpRegs);
++
++        SafeUnderrunProtect protect(this, 12);
+         switch(op) {
+-            case LIR_lduc2ui:
+-                LDUB32(ra, d, rr);
+-                break;
+-            case LIR_ldus2ui:
+-                LDUH32(ra, d, rr);
+-                break;
+-            case LIR_ldi:
+-                LDSW32(ra, d, rr);
+-                break;
+-            case LIR_ldc2i:
+-                LDSB32(ra, d, rr);
+-                break;
+-            case LIR_lds2i:
+-                LDSH32(ra, d, rr);
+-                break;
++            case LIR_lduc2ui: LDUB32(ra, d, rr); break;
++            case LIR_ldus2ui: LDUH32(ra, d, rr); break;
++            case LIR_ldi    : LDSW32(ra, d, rr); break;
++            case LIR_ldc2i  : LDSB32(ra, d, rr); break;
++            case LIR_lds2i  : LDSH32(ra, d, rr); break;
+             default:
+                 NanoAssertMsg(0, "asm_load32 should never receive this LIR opcode");
+                 return;
+         }
++        freeResourcesOf(ins);
++        if (!base->isop(LIR_allocp) && !base->isInReg()) {
++            NanoAssert(ra == rr);
++            findSpecificRegForUnallocated(base, ra);
++        }
+     }
+ 
+     void Assembler::asm_cmov(LIns* ins)
+     {
+-        underrunProtect(4);
+         LOpcode op = ins->opcode();
+         LIns* condval = ins->oprnd1();
+         LIns* iftrue  = ins->oprnd2();
+@@ -1329,7 +1360,7 @@
+                   (op == LIR_cmovd && iftrue->isD() && iffalse->isD()));
+ 
+         RegisterMask rm = (op == LIR_cmovi) ? GpRegs : FpRegs;
+-        const Register rr = deprecated_prepResultReg(ins, rm);
++        const Register rr = prepareResultReg(ins, rm);
+         const Register iffalsereg = findRegFor(iffalse, rm & ~rmask(rr));
+         bool isIcc = true;
+ 
+@@ -1345,7 +1376,9 @@
+                 case LIR_leui: MOVGU (iffalsereg, rr); break;
+                 case LIR_gtui: MOVLEU(iffalsereg, rr); break;
+                 case LIR_geui: MOVCS (iffalsereg, rr); break;
+-                debug_only( default: NanoAssert(0); break; )
++                default:
++                    NanoAssertMsg(0, "asm_comv should never receive this cond opcode");
++                    return;
+             }
+         } else {
+             switch (condval->opcode()) {
+@@ -1364,10 +1397,13 @@
+                 case LIR_ltd:  FMOVDFUGE(iffalsereg, rr); isIcc = false; break;
+                 case LIR_ged:  FMOVDFUL (iffalsereg, rr); isIcc = false; break;
+                 case LIR_gtd:  FMOVDFULE(iffalsereg, rr); isIcc = false; break;
+-                debug_only( default: NanoAssert(0); break; )
++                default:
++                    NanoAssertMsg(0, "asm_comv should never receive this cond opcode");
++                    return;
+             }
+         }
+ 
++        freeResourcesOf(ins);
+         /*const Register iftruereg =*/ findSpecificRegFor(iftrue, rr);
+         if (isIcc)
+             asm_cmp(condval);
+@@ -1378,16 +1414,16 @@
+ 
+     void Assembler::asm_param(LIns* ins)
+     {
+-        underrunProtect(12);
+         uint32_t a = ins->paramArg();
+         NanoAssertMsg(ins->paramKind() == 0, "savedRegs are not used on SPARC");
+ 
+-        if (a < sizeof(argRegs)/sizeof(argRegs[0])) { // i0 - i5
++        if (a < sizeof(argRegs) / sizeof(argRegs[0])) { // i0 - i5
+             prepareResultReg(ins, rmask(argRegs[a]));
+         } else {
+             // Incoming arg is on stack
+             Register r = prepareResultReg(ins, GpRegs);
+             int32_t d = a * sizeof (intptr_t) + kLinkageAreaSize;
++            SafeUnderrunProtect protect(this, 12);
+             LDSW32(FP, d, r);
+         }
+         freeResourcesOf(ins);
+@@ -1395,100 +1431,102 @@
+ 
+     void Assembler::asm_immi(LIns* ins)
+     {
+-        underrunProtect(8);
+-        Register rr = deprecated_prepResultReg(ins, GpRegs);
++        Register rr = prepareResultReg(ins, GpRegs);
++        SafeUnderrunProtect protect(this, 12);
+         int32_t val = ins->immI();
+         if (val == 0)
+             XOR(rr, rr, rr);
+         else
+             SET32(val, rr);
++        freeResourcesOf(ins);
+     }
+ 
+     void Assembler::asm_immd(LIns* ins)
+     {
+-        underrunProtect(64);
+-        Register rr = ins->deprecated_getReg();
+-        if (rr != deprecated_UnknownReg)
+-            {
+-                // @todo -- add special-cases for 0 and 1
+-                _allocator.retire(rr);
+-                ins->clearReg();
+-                NanoAssert((rmask(rr) & FpRegs) != 0);
+-                findMemFor(ins);
+-                int d = deprecated_disp(ins);
+-                LDDF32(FP, d, rr);
+-            }
++        SafeUnderrunProtect protect(this, 64);
++        if (ins->isInReg()) {
++            Register rr = ins->getReg();
++            // @todo -- add special-cases for 0 and 1
++            _allocator.retire(rr);
++            ins->clearReg();
++            NanoAssert((rmask(rr) & FpRegs) != 0);
++            findMemFor(ins);
++            int d = arDisp(ins);
++            LDDF32(FP, d, rr);
++        }
+ 
+         // @todo, if we used xor, ldsd, fldz, etc above, we don't need mem here
+-        int d = deprecated_disp(ins);
+-        deprecated_freeRsrcOf(ins);
+-        if (d)
+-            {
+-                STW32(L2, d+4, FP);
+-                SET32(ins->immDlo(), L2);
+-                STW32(L2, d, FP);
+-                SET32(ins->immDhi(), L2);
+-            }
++        int d = arDisp(ins);
++        if (d) {
++            STW32(L2, d+4, FP);
++            SET32(ins->immDlo(), L2);
++            STW32(L2, d, FP);
++            SET32(ins->immDhi(), L2);
++        }
++        freeResourcesOf(ins);
+     }
+ 
+     void Assembler::asm_fneg(LIns* ins)
+     {
+-        underrunProtect(4);
+-        Register rr = deprecated_prepResultReg(ins, FpRegs);
++        Register rr = prepareResultReg(ins, FpRegs);
+         LIns* lhs = ins->oprnd1();
+ 
+-        // lhs into reg, prefer same reg as result
+-        // if this is last use of lhs in reg, we can re-use result reg
+-        // else, lhs already has a different reg assigned
+-        Register ra = ( !lhs->isInReg()
+-                      ? findSpecificRegFor(lhs, rr)
+-                      : findRegFor(lhs, FpRegs) );
++        // If 'lhs' isn't in a register, it can be clobbered by 'ins'.
++        Register ra = lhs->isInReg() ? lhs->getReg() : rr;
+ 
+         FNEGD(ra, rr);
++
++        freeResourcesOf(ins);
++        if (!lhs->isInReg()) {
++            NanoAssert(ra == rr);
++            findSpecificRegForUnallocated(lhs, ra);
++        }
+     }
+ 
+     void Assembler::asm_fop(LIns* ins)
+     {
+-        underrunProtect(4);
+         LOpcode op = ins->opcode();
+-        LIns *lhs = ins->oprnd1();
+-        LIns *rhs = ins->oprnd2();
++        LIns* lhs = ins->oprnd1();
++        LIns* rhs = ins->oprnd2();
+ 
+         RegisterMask allow = FpRegs;
+         Register ra, rb;
+         findRegFor2(allow, lhs, ra, allow, rhs, rb);
+-        Register rr = deprecated_prepResultReg(ins, allow);
++        Register rr = prepareResultReg(ins, allow);
+ 
+-        if (op == LIR_addd)
+-            FADDD(ra, rb, rr);
+-        else if (op == LIR_subd)
+-            FSUBD(ra, rb, rr);
+-        else if (op == LIR_muld)
+-            FMULD(ra, rb, rr);
+-        else //if (op == LIR_divd)
+-            FDIVD(ra, rb, rr);
++        switch (op) {
++            case LIR_addd: FADDD(ra, rb, rr); break;
++            case LIR_subd: FSUBD(ra, rb, rr); break;
++            case LIR_muld: FMULD(ra, rb, rr); break;
++            case LIR_divd: FDIVD(ra, rb, rr); break;
++            default:
++                NanoAssertMsg(0, "asm_fop should never receive this opcode");
++                return;
++        }
+ 
++        freeResourcesOf(ins);
+     }
+ 
+     void Assembler::asm_i2d(LIns* ins)
+     {
+-        underrunProtect(32);
+         // where our result goes
+-        Register rr = deprecated_prepResultReg(ins, FpRegs);
++        Register rr = prepareResultReg(ins, FpRegs);
++        SafeUnderrunProtect protect(this, 32);
+         int d = findMemFor(ins->oprnd1());
+         FITOD(rr, rr);
+         LDDF32(FP, d, rr);
++        freeResourcesOf(ins);
+     }
+ 
+     void Assembler::asm_ui2d(LIns* ins)
+     {
+-        underrunProtect(72);
+         // where our result goes
+-        Register rr = deprecated_prepResultReg(ins, FpRegs);
++        Register rr = prepareResultReg(ins, FpRegs);
+         Register rt = registerAllocTmp(FpRegs & ~(rmask(rr)));
+         Register gr = findRegFor(ins->oprnd1(), GpRegs);
+         int disp = -8;
+ 
++        SafeUnderrunProtect protect(this, 72);
+         FABSS(rr, rr);
+         FSUBD(rt, rr, rr);
+         LDDF32(SP, disp, rr);
+@@ -1497,37 +1535,37 @@
+         STWI(gr, disp+4, SP);
+         STWI(G1, disp, SP);
+         SETHI(0x43300000, G1);
++        freeResourcesOf(ins);
+     }
+ 
+     void Assembler::asm_d2i(LIns* ins) {
+-        underrunProtect(28);
+-        LIns *lhs = ins->oprnd1();
++        LIns* lhs = ins->oprnd1();
+         Register rr = prepareResultReg(ins, GpRegs);
+         Register ra = findRegFor(lhs, FpRegs);
+         int d = findMemFor(ins);
++        SafeUnderrunProtect protect(this, 28);
+         LDSW32(FP, d, rr);
+-        STF32(ra, d, FP);
+-        FDTOI(ra, ra);
++        STF32(F28, d, FP);
++        FDTOI(ra, F28);
+         freeResourcesOf(ins);
+     }
+ 
+     void Assembler::asm_nongp_copy(Register r, Register s)
+     {
+-        underrunProtect(4);
+         NanoAssert((rmask(r) & FpRegs) && (rmask(s) & FpRegs));
+         FMOVD(s, r);
+     }
+ 
+-    NIns * Assembler::asm_branchd(bool branchOnFalse, LIns *cond, NIns *targ)
++    NIns* Assembler::asm_branchd(bool branchOnFalse, LIns* cond, NIns* targ)
+     {
+-        NIns *at = 0;
++        NIns* at = 0;
+         LOpcode condop = cond->opcode();
+         NanoAssert(isCmpDOpcode(condop));
+-        underrunProtect(32);
++        SafeUnderrunProtect protect(this, 32);
+         intptr_t tt = ((intptr_t)targ - (intptr_t)_nIns + 8) >> 2;
+         // !targ means that it needs patch.
+         if( !(isIMM22((int32_t)tt)) || !targ ) {
+-            JMP_long_nocheck((intptr_t)targ);
++            JMP_long((intptr_t)targ);
+             at = _nIns;
+             NOP();
+             BA(0, 5);
+@@ -1536,39 +1574,35 @@
+         NOP();
+ 
+         // produce the branch
+-        if (branchOnFalse)
+-            {
+-                if (condop == LIR_eqd)
+-                    FBNE(0, tt);
+-                else if (condop == LIR_led)
+-                    FBUG(0, tt);
+-                else if (condop == LIR_ltd)
+-                    FBUGE(0, tt);
+-                else if (condop == LIR_ged)
+-                    FBUL(0, tt);
+-                else //if (condop == LIR_gtd)
+-                    FBULE(0, tt);
++        if (branchOnFalse) {
++            switch (condop) {
++                case LIR_eqd: FBNE (0, tt); break;
++                case LIR_led: FBUG (0, tt); break;
++                case LIR_ltd: FBUGE(0, tt); break;
++                case LIR_ged: FBUL (0, tt); break;
++                case LIR_gtd: FBULE(0, tt); break;
++                default:
++                    NanoAssertMsg(0, "asm_branchd should never receive this cond opcode");
++                    return;
+             }
+-        else // op == LIR_xt
+-            {
+-                if (condop == LIR_eqd)
+-                    FBE(0, tt);
+-                else if (condop == LIR_led)
+-                    FBLE(0, tt);
+-                else if (condop == LIR_ltd)
+-                    FBL(0, tt);
+-                else if (condop == LIR_ged)
+-                    FBGE(0, tt);
+-                else //if (condop == LIR_gtd)
+-                    FBG(0, tt);
++        } else { // op == LIR_xt
++            switch (condop) {
++                case LIR_eqd: FBE (0, tt); break;
++                case LIR_led: FBLE(0, tt); break;
++                case LIR_ltd: FBL (0, tt); break;
++                case LIR_ged: FBGE(0, tt); break;
++                case LIR_gtd: FBG (0, tt); break;
++                default:
++                    NanoAssertMsg(0, "asm_branchd should never receive this cond opcode");
++                    return;
+             }
++        }
+         asm_cmpd(cond);
+         return at;
+     }
+ 
+-    void Assembler::asm_cmpd(LIns *cond)
++    void Assembler::asm_cmpd(LIns* cond)
+     {
+-        underrunProtect(4);
+         LIns* lhs = cond->oprnd1();
+         LIns* rhs = cond->oprnd2();
+ 
+@@ -1582,11 +1616,6 @@
+     {
+     }
+ 
+-    Register Assembler::asm_binop_rhs_reg(LIns* ins)
+-    {
+-        return deprecated_UnknownReg;
+-    }
+-
+     void Assembler::nativePageSetup()
+     {
+         NanoAssert(!_inExit);
+@@ -1606,11 +1635,12 @@
+     void
+     Assembler::underrunProtect(int n)
+     {
+-        NIns *eip = _nIns;
++        NIns* eip = _nIns;
++        NanoAssertMsg(n <= LARGEST_UNDERRUN_PROT, "constant LARGEST_UNDERRUN_PROT is too small %d");
+         // This may be in a normal code chunk or an exit code chunk.
+-        if (eip - n < codeStart) {
++        if ((intptr_t)eip - n < (intptr_t)codeStart) {
+             codeAlloc(codeStart, codeEnd, _nIns verbose_only(, codeBytes));
+-            JMP_long_nocheck((intptr_t)eip);
++            JMP_long((intptr_t)eip);
+         }
+     }
+ 
+@@ -1619,7 +1649,7 @@
+         genEpilogue();
+         releaseRegisters();
+         assignSavedRegs();
+-        LIns *val = ins->oprnd1();
++        LIns* val = ins->oprnd1();
+         if (ins->isop(LIR_reti)) {
+             findSpecificRegFor(val, retRegs[0]);
+         } else {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/firefox6-28-patch-for-debugging.diff	Mon Aug 15 02:22:00 2011 +0000
@@ -0,0 +1,157 @@
+diff --git a/js/src/jsexn.cpp b/js/src/jsexn.cpp
+index 10edf66..e7e054a 100644
+--- a/js/src/jsexn.cpp
++++ b/js/src/jsexn.cpp
+@@ -855,7 +855,10 @@ static JSBool
+ exn_toSource(JSContext *cx, uintN argc, Value *vp)
+ {
+     JSString *name, *message, *filename, *lineno_as_str, *result;
+-    jsval localroots[3] = {JSVAL_NULL, JSVAL_NULL, JSVAL_NULL};
++    jsval localroots[3];
++    localroots[0] = JSVAL_NULL;
++    localroots[1] = JSVAL_NULL;
++    localroots[2] = JSVAL_NULL;
+     size_t lineno_length, name_length, message_length, filename_length, length;
+     jschar *chars, *cp;
+ 
+diff --git a/js/src/jsxml.cpp b/js/src/jsxml.cpp
+index 7fa3bc1..648ca10 100644
+--- a/js/src/jsxml.cpp
++++ b/js/src/jsxml.cpp
+@@ -3777,7 +3777,9 @@ GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
+     if (!JSID_IS_VOID(funid))
+         return GetXMLFunction(cx, obj, funid, vp);
+ 
+-    jsval roots[2] = { OBJECT_TO_JSVAL(nameqn), JSVAL_NULL };
++    jsval roots[2];
++    roots[0] = OBJECT_TO_JSVAL(nameqn);
++    roots[1] = JSVAL_NULL;
+     AutoArrayRooter tvr(cx, JS_ARRAY_LENGTH(roots), Valueify(roots));
+ 
+     listobj = js_NewXMLObject(cx, JSXML_CLASS_LIST);
+diff --git a/js/src/shell/jsworkers.cpp b/js/src/shell/jsworkers.cpp
+index 684a9d1..da02ede 100644
+--- a/js/src/shell/jsworkers.cpp
++++ b/js/src/shell/jsworkers.cpp
+@@ -344,7 +344,9 @@ class Event
+             return fail;
+ 
+         // Call event handler.
+-        jsval argv[1] = { OBJECT_TO_JSVAL(obj) };
++        jsval argv[1]; 
++        argv[0] = OBJECT_TO_JSVAL(obj);
++
+         jsval rval = JSVAL_VOID;
+         return Result(JS_CallFunctionName(cx, thisobj, methodName, 1, argv, &rval));
+     }
+diff --git a/js/src/xpconnect/src/xpccomponents.cpp b/js/src/xpconnect/src/xpccomponents.cpp
+index 1c141f9..a4dc9d9 100644
+--- a/js/src/xpconnect/src/xpccomponents.cpp
++++ b/js/src/xpconnect/src/xpccomponents.cpp
+@@ -2255,7 +2255,8 @@ nsXPCConstructor::CallOrConstruct(nsIXPConnectWrappedNative *wrapper,
+         return ThrowAndFail(NS_ERROR_XPC_CANT_CREATE_WN, cx, _retval);
+     }
+ 
+-    jsval ctorArgs[1] = {OBJECT_TO_JSVAL(iidObj)};
++    jsval ctorArgs[1];
++    ctorArgs[0] = OBJECT_TO_JSVAL(iidObj);
+     jsval val;
+ 
+     if(!JS_CallFunctionName(cx, cidObj, "createInstance", 1, ctorArgs, &val) ||
+diff --git a/js/src/xpconnect/src/xpcquickstubs.cpp b/js/src/xpconnect/src/xpcquickstubs.cpp
+index 09ad639..d9b55a1 100644
+--- a/js/src/xpconnect/src/xpcquickstubs.cpp
++++ b/js/src/xpconnect/src/xpcquickstubs.cpp
+@@ -218,7 +218,9 @@ ReifyPropertyOps(JSContext *cx, JSObject *obj, jsid id,
+                  JSObject **getterobjp, JSObject **setterobjp)
+ {
+     // Generate both getter and setter and stash them in the prototype.
+-    jsval roots[2] = { JSVAL_NULL, JSVAL_NULL };
++    jsval roots[2];
++    roots[0] = JSVAL_NULL;
++    roots[1] = JSVAL_NULL;
+     js::AutoArrayRooter tvr(cx, JS_ARRAY_LENGTH(roots), roots);
+ 
+     uintN attrs = JSPROP_SHARED;
+diff --git a/js/src/xpconnect/src/xpcwrappedjsclass.cpp b/js/src/xpconnect/src/xpcwrappedjsclass.cpp
+index 3906478..f544b7e 100644
+--- a/js/src/xpconnect/src/xpcwrappedjsclass.cpp
++++ b/js/src/xpconnect/src/xpcwrappedjsclass.cpp
+@@ -310,7 +310,8 @@ nsXPCWrappedJSClass::CallQueryInterfaceOnJSObject(XPCCallContext& ccx,
+         uint32 oldOpts =
+           JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_DONT_REPORT_UNCAUGHT);
+ 
+-        jsval args[1] = {OBJECT_TO_JSVAL(id)};
++        jsval args[1];
++        args[0] = OBJECT_TO_JSVAL(id);
+         success = JS_CallFunctionValue(cx, jsobj, fun, 1, args, &retval);
+ 
+         JS_SetOptions(cx, oldOpts);
+diff --git a/dom/plugins/base/nsNPAPIPlugin.cpp b/dom/plugins/base/nsNPAPIPlugin.cpp
+index 17773fd..84ba0e0 100644
+--- a/dom/plugins/base/nsNPAPIPlugin.cpp
++++ b/dom/plugins/base/nsNPAPIPlugin.cpp
+@@ -1635,7 +1635,10 @@ _evaluate(NPP npp, NPObject* npobj, NPString *script, NPVariant *result)
+   OBJ_TO_INNER_OBJECT(cx, obj);
+ 
+   // Root obj and the rval (below).
+-  jsval vec[] = { OBJECT_TO_JSVAL(obj), JSVAL_NULL };
++  jsval vec[2] ;
++  vec[0] = OBJECT_TO_JSVAL(obj);
++  vec[1] = JSVAL_NULL;
++
+   js::AutoArrayRooter tvr(cx, NS_ARRAY_LENGTH(vec), vec);
+   jsval *rval = &vec[1];
+ 
+diff --git a/ipc/testshell/TestShellParent.cpp b/ipc/testshell/TestShellParent.cpp
+index 2b5a03a..beefcb8 100644
+--- a/ipc/testshell/TestShellParent.cpp
++++ b/ipc/testshell/TestShellParent.cpp
+@@ -131,7 +131,8 @@ TestShellCommandParent::RunCallback(const nsString& aResponse)
+   JSString* str = JS_NewUCStringCopyN(mCx, aResponse.get(), aResponse.Length());
+   NS_ENSURE_TRUE(str, JS_FALSE);
+ 
+-  jsval argv[] = { STRING_TO_JSVAL(str) };
++  jsval argv[1];
++  argv[0] = STRING_TO_JSVAL(str);
+   int argc = NS_ARRAY_LENGTH(argv);
+ 
+   jsval rval;
+diff --git a/xpcom/build/Makefile.in b/xpcom/build/Makefile.in
+index 52a110b..2ff9f82 100644
+--- a/xpcom/build/Makefile.in
++++ b/xpcom/build/Makefile.in
+@@ -186,5 +186,9 @@
+ endif
+ endif # WINNT
+ 
++ifdef SOLARIS_SUNPRO_CXX
++SSE.$(OBJ_SUFFIX): CXXFLAGS += -xO4
++endif
++
+ export:: $(XPCOM_GLUE_SRC_CSRCS) $(XPCOM_GLUE_SRC_CPPSRCS) $(XPCOM_GLUENS_SRC_CPPSRCS)
+ 	$(INSTALL) $^ .
+diff --git a/xpcom/glue/Makefile.in b/xpcom/glue/Makefile.in
+index 3768712..116f8cd 100644
+--- a/xpcom/glue/Makefile.in
++++ b/xpcom/glue/Makefile.in
+@@ -170,3 +170,7 @@ endif
+ ifdef TARGET_XPCOM_ABI
+ DEFINES += -DTARGET_XPCOM_ABI=\"$(TARGET_XPCOM_ABI)\"
+ endif
++
++ifdef SOLARIS_SUNPRO_CXX
++SSE.$(OBJ_SUFFIX): CXXFLAGS += -xO4
++endif
+diff --git a/xpcom/glue/nomozalloc/Makefile.in b/xpcom/glue/nomozalloc/Makefile.in
+index 0838cf1..1a4d362 100644
+--- a/xpcom/glue/nomozalloc/Makefile.in
++++ b/xpcom/glue/nomozalloc/Makefile.in
+@@ -103,3 +103,7 @@ DEFINES += -DTARGET_XPCOM_ABI=\"$(TARGET_XPCOM_ABI)\"
+ endif
+ 
+ DEFINES += -DMOZ_NO_MOZALLOC
++
++ifdef SOLARIS_SUNPRO_CXX
++SSE.$(OBJ_SUFFIX): CXXFLAGS += -xO4
++endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/firefox6-32-yasm.diff	Mon Aug 15 02:22:00 2011 +0000
@@ -0,0 +1,19 @@
+--- a/configure	2011-06-20 13:47:29.430038980 +0800
++++ b/configure	2011-06-20 13:51:41.439509615 +0800
+@@ -14119,7 +14119,7 @@
+   _YASM_VER_FILTER='s|.* \([0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}\).*|\1|p'
+   
+ 
+-  YASM_VERSION=`yasm --version | sed -ne "$_YASM_VER_FILTER"`
++  YASM_VERSION=`$YASM --version | sed -ne "$_YASM_VER_FILTER"`
+   _YASM_MAJOR_VERSION=`echo ${YASM_VERSION} | $AWK -F\. '{ print $1 }'`
+   _YASM_MINOR_VERSION=`echo ${YASM_VERSION} | $AWK -F\. '{ print $2 }'`
+   _YASM_RELEASE=`      echo ${YASM_VERSION} | $AWK -F\. '{ print $3 }'`
+@@ -14682,7 +14682,6 @@
+ VPX_X86_ASM=
+ VPX_ARM_ASM=
+ MOZ_LIBJPEG_TURBO=1
+-LIBJPEG_TURBO_AS=
+ LIBJPEG_TURBO_ASFLAGS=
+ LIBJPEG_TURBO_X86_ASM=
+ LIBJPEG_TURBO_X64_ASM=
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/firefox6-33-wifi.diff	Mon Aug 15 02:22:00 2011 +0000
@@ -0,0 +1,20 @@
+--- a/netwerk/wifi/nsWifiScannerSolaris.cpp	Thu Jul  7 16:38:41 2011
+--- b/netwerk/wifi/nsWifiScannerSolaris.cpp	Thu Jul  7 16:38:41 2011
+@@ -174,7 +174,7 @@
+     nsCOMArray<nsIWifiListener> currentListeners;
+ 
+     {
+-      MonitorAutoEnter mon(mMonitor);
++      ReentrantMonitorAutoEnter mon(mReentrantMonitor);
+ 
+       for (PRUint32 i = 0; i < mListeners.Length(); i++) {
+         if (!mListeners[i].mHasSentData || accessPointsChanged) {
+@@ -223,7 +223,7 @@
+ 
+     LOG(("waiting on monitor\n"));
+ 
+-    MonitorAutoEnter mon(mMonitor);
++    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
+     mon.Wait(PR_SecondsToInterval(60));
+   }
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/firefox6-34-xbgr-plugin.diff	Mon Aug 15 02:22:00 2011 +0000
@@ -0,0 +1,133 @@
+diff --git a/dom/plugins/ipc/PluginInstanceChild.cpp b/dom/plugins/ipc/PluginInstanceChild.cpp
+--- a/dom/plugins/ipc/PluginInstanceChild.cpp
++++ b/dom/plugins/ipc/PluginInstanceChild.cpp
+@@ -276,17 +276,17 @@ PluginInstanceChild::NPN_GetValue(NPNVar
+                                   void* aValue)
+ {
+     PLUGIN_LOG_DEBUG(("%s (aVar=%i)", FULLFUNCTION, (int) aVar));
+     AssertPluginThread();
+ 
+     switch(aVar) {
+ 
+     case NPNVSupportsWindowless:
+-#if defined(OS_LINUX) || defined(OS_WIN)
++#if defined(OS_LINUX) || defined(MOZ_X11) || defined(OS_WIN)
+         *((NPBool*)aValue) = true;
+ #else
+         *((NPBool*)aValue) = false;
+ #endif
+         return NPERR_NO_ERROR;
+ 
+ #if (MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6)
+     case NPNVSupportsWindowlessLocal: {
+@@ -295,17 +295,17 @@ PluginInstanceChild::NPN_GetValue(NPNVar
+         // we should set local rendering to false in order to render X-Plugin
+         // there is no possibility to change it later on maemo5 platform
+         mMaemoImageRendering = (!(graphicsSystem && !strcmp(graphicsSystem, "native")));
+ #endif
+         *((NPBool*)aValue) = mMaemoImageRendering;
+         return NPERR_NO_ERROR;
+     }
+ #endif
+-#if defined(OS_LINUX)
++#if defined(MOZ_X11)
+     case NPNVSupportsXEmbedBool:
+         *((NPBool*)aValue) = true;
+         return NPERR_NO_ERROR;
+ 
+     case NPNVToolkit:
+         *((NPNToolkitType*)aValue) = NPNVGtk2;
+         return NPERR_NO_ERROR;
+ 
+@@ -2346,17 +2346,26 @@ PluginInstanceChild::CreateOptSurface(vo
+     Display* dpy = mWsInfo.display;
+     Screen* screen = DefaultScreenOfDisplay(dpy);
+     if (format == gfxASurface::ImageFormatRGB24 &&
+         DefaultDepth(dpy, DefaultScreen(dpy)) == 16) {
+         format = gfxASurface::ImageFormatRGB16_565;
+     }
+ 
+     if (mSurfaceType == gfxASurface::SurfaceTypeXlib) {
+-        XRenderPictFormat* xfmt = gfxXlibSurface::FindRenderFormat(dpy, format);
++        if (!mIsTransparent  || mBackground) {
++            Visual* defaultVisual = DefaultVisualOfScreen(screen);
++            mCurrentSurface =
++                gfxXlibSurface::Create(screen, defaultVisual,
++                                       gfxIntSize(mWindow.width,
++                                                  mWindow.height));
++            return mCurrentSurface != nsnull;
++        }
++
++        XRenderPictFormat* xfmt = XRenderFindStandardFormat(dpy, PictStandardARGB32);
+         if (!xfmt) {
+             NS_ERROR("Need X falback surface, but FindRenderFormat failed");
+             return false;
+         }
+         mCurrentSurface =
+             gfxXlibSurface::Create(screen, xfmt,
+                                    gfxIntSize(mWindow.width,
+                                               mWindow.height));
+@@ -2720,17 +2729,17 @@ PluginInstanceChild::PaintRectToSurface(
+ #ifdef MOZ_X11
+     if (mIsTransparent && (GetQuirks() & PluginModuleChild::QUIRK_FLASH_EXPOSE_COORD_TRANSLATION)) {
+         // Work around a bug in Flash up to 10.1 d51 at least, where expose event
+         // top left coordinates within the plugin-rect and not at the drawable
+         // origin are misinterpreted.  (We can move the top left coordinate
+         // provided it is within the clipRect.), see bug 574583
+         plPaintRect.SetRect(0, 0, aRect.XMost(), aRect.YMost());
+     }
+-    if (renderSurface->GetType() != gfxASurface::SurfaceTypeXlib) {
++    if (mHelperSurface) {
+         // On X11 we can paint to non Xlib surface only with HelperSurface
+ #if (MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6)
+         // Don't use mHelperSurface if surface is image and mMaemoImageRendering is TRUE
+         if (!mMaemoImageRendering ||
+             renderSurface->GetType() != gfxASurface::SurfaceTypeImage)
+ #endif
+         renderSurface = mHelperSurface;
+     }
+@@ -2929,17 +2938,18 @@ PluginInstanceChild::ShowPluginFrame()
+          this, haveTransparentPixels ? " with alpha" : "",
+          rect.x, rect.y, rect.width, rect.height,
+          mCurrentSurface->GetSize().width, mCurrentSurface->GetSize().height));
+ 
+     if (CanPaintOnBackground()) {
+         PLUGIN_LOG_DEBUG(("  (on background)"));
+         // Source the background pixels ...
+         {
+-            nsRefPtr<gfxContext> ctx = new gfxContext(mCurrentSurface);
++            nsRefPtr<gfxContext> ctx =
++                new gfxContext(mHelperSurface ? mHelperSurface : mCurrentSurface);
+             ctx->SetSource(mBackground);
+             ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
+             ctx->Rectangle(gfxRect(rect.x, rect.y, rect.width, rect.height));
+             ctx->Fill();
+         }
+         // ... and hand off to the plugin
+         // BEWARE: mBackground may die during this call
+         PaintRectToSurface(rect, mCurrentSurface, gfxRGBA(0.0, 0.0, 0.0, 0.0));
+@@ -3326,23 +3336,17 @@ PluginInstanceChild::SwapSurfaces()
+     mBackSurfaceActor = tmpactor;
+ #endif
+ 
+     // Outdated back surface... not usable anymore due to changed plugin size.
+     // Dropping obsolete surface
+     if (mCurrentSurface && mBackSurface &&
+         (mCurrentSurface->GetSize() != mBackSurface->GetSize() ||
+          mCurrentSurface->GetContentType() != mBackSurface->GetContentType())) {
+-        mCurrentSurface = nsnull;
+-#ifdef XP_WIN
+-        if (mCurrentSurfaceActor) {
+-            PPluginSurfaceChild::Send__delete__(mCurrentSurfaceActor);
+-            mCurrentSurfaceActor = NULL;
+-        }
+-#endif
++        ClearCurrentSurface();
+     }
+ }
+ 
+ void
+ PluginInstanceChild::ClearCurrentSurface()
+ {
+     mCurrentSurface = nsnull;
+ #ifdef XP_WIN
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/firefox6-36-gtkembed.diff	Mon Aug 15 02:22:00 2011 +0000
@@ -0,0 +1,8846 @@
+diff --git a/embedding/browser/gtk/Makefile.in b/embedding/browser/gtk/Makefile.in
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/Makefile.in
+@@ -0,0 +1,54 @@
++# 
++# ***** BEGIN LICENSE BLOCK *****
++# Version: MPL 1.1/GPL 2.0/LGPL 2.1
++#
++# The contents of this file are subject to the Mozilla Public License Version
++# 1.1 (the "License"); you may not use this file except in compliance with
++# the License. You may obtain a copy of the License at
++# http://www.mozilla.org/MPL/
++#
++# Software distributed under the License is distributed on an "AS IS" basis,
++# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++# for the specific language governing rights and limitations under the
++# License.
++#
++# The Original Code is the Mozilla browser.
++#
++# The Initial Developer of the Original Code is
++# Christopher Blizzard.
++# Portions created by the Initial Developer are Copyright (C) 1999
++# the Initial Developer. All Rights Reserved.
++#
++# Contributor(s):
++#   Christopher Blizzard <[email protected]>
++#
++# Alternatively, the contents of this file may be used under the terms of
++# either the GNU General Public License Version 2 or later (the "GPL"), or
++# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++# in which case the provisions of the GPL or the LGPL are applicable instead
++# of those above. If you wish to allow use of your version of this file only
++# under the terms of either the GPL or the LGPL, and not to allow others to
++# use your version of this file under the terms of the MPL, indicate your
++# decision by deleting the provisions above and replace them with the notice
++# and other provisions required by the GPL or the LGPL. If you do not delete
++# the provisions above, a recipient may use your version of this file under
++# the terms of any one of the MPL, the GPL or the LGPL.
++#
++# ***** END LICENSE BLOCK *****
++
++DEPTH		= ../../..
++topsrcdir	= @top_srcdir@
++srcdir		= @srcdir@
++VPATH		= @srcdir@
++
++include $(DEPTH)/config/autoconf.mk
++
++MODULE		= gtkembedmoz
++
++DIRS=src
++
++ifdef ENABLE_TESTS
++TOOL_DIRS  += tests
++endif
++
++include $(topsrcdir)/config/rules.mk
+diff --git a/embedding/browser/gtk/src/EmbedCertificates.cpp b/embedding/browser/gtk/src/EmbedCertificates.cpp
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/src/EmbedCertificates.cpp
+@@ -0,0 +1,253 @@
++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
++/* vim:set ts=2 sw=2 sts=2 tw=80 et cindent: */
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * Netscape Communications Corporation.
++ * Portions created by the Initial Developer are Copyright (C) 2001
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *   Terry Hayes <[email protected]>
++ *   Javier Delgadillo <[email protected]>
++ *   Oleg Romashin <[email protected]>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++/**
++ * Derived from nsNSSDialogs http://landfill.mozilla.org/mxr-test/seamonkey/source/security/manager/pki/src/nsNSSDialogs.cpp
++ */
++#include <strings.h>
++#include "nsIURI.h"
++#include "EmbedPrivate.h"
++#include "nsServiceManagerUtils.h"
++#include "nsIWebNavigationInfo.h"
++#include "nsDocShellCID.h"
++#include "nsCOMPtr.h"
++#ifdef MOZILLA_INTERNAL_API
++#include "nsString.h"
++#include "nsXPIDLString.h"
++#include "nsReadableUtils.h"
++#else
++#include "nsStringAPI.h"
++#endif
++#include "nsIPrompt.h"
++#include "nsIDOMWindowInternal.h"
++#include "nsIComponentManager.h"
++#include "nsIServiceManager.h"
++#include "nsIStringBundle.h"
++#include "nsIInterfaceRequestor.h"
++#include "nsIInterfaceRequestorUtils.h"
++#include "nsIX509Cert.h"
++#include "nsIX509CertDB.h"
++#include "nsIDateTimeFormat.h"
++#include "nsDateTimeFormatCID.h"
++#include "EmbedCertificates.h"
++#include "nsIKeygenThread.h"
++#include "nsIX509CertValidity.h"
++#include "nsICRLInfo.h"
++#include "gtkmozembed.h"
++
++#define PIPSTRING_BUNDLE_URL "chrome://pippki/locale/pippki.properties"
++
++EmbedCertificates::EmbedCertificates(void)
++{
++}
++
++EmbedCertificates::~EmbedCertificates()
++{
++}
++
++NS_IMPL_THREADSAFE_ADDREF(EmbedCertificates)
++NS_IMPL_THREADSAFE_RELEASE(EmbedCertificates)
++NS_INTERFACE_MAP_BEGIN(EmbedCertificates)
++NS_INTERFACE_MAP_ENTRY(nsITokenPasswordDialogs)
++NS_INTERFACE_MAP_ENTRY(nsICertificateDialogs)
++NS_INTERFACE_MAP_ENTRY(nsIClientAuthDialogs)
++NS_INTERFACE_MAP_ENTRY(nsICertPickDialogs)
++NS_INTERFACE_MAP_ENTRY(nsITokenDialogs)
++NS_INTERFACE_MAP_ENTRY(nsIGeneratingKeypairInfoDialogs)
++NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMCryptoDialogs)
++NS_INTERFACE_MAP_END
++
++nsresult
++EmbedCertificates::Init(void)
++{
++  nsresult rv;
++  nsCOMPtr<nsIStringBundleService> service =
++           do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
++  if (NS_FAILED(rv)) return NS_OK;
++  rv = service->CreateBundle(PIPSTRING_BUNDLE_URL,
++                             getter_AddRefs(mPIPStringBundle));
++  return NS_OK;
++}
++
++nsresult
++EmbedCertificates::SetPassword(nsIInterfaceRequestor *ctx,
++                          const PRUnichar *tokenName, PRBool* _canceled)
++{
++  *_canceled = PR_FALSE;
++  return NS_OK;
++}
++
++nsresult
++EmbedCertificates::GetPassword(nsIInterfaceRequestor *ctx,
++                          const PRUnichar *tokenName,
++                          PRUnichar **_password,
++                          PRBool* _canceled)
++{
++  *_canceled = PR_FALSE;
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++EmbedCertificates::CrlImportStatusDialog(nsIInterfaceRequestor *ctx, nsICRLInfo *crl)
++{
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++EmbedCertificates::ConfirmDownloadCACert(nsIInterfaceRequestor *ctx,
++                                    nsIX509Cert *cert,
++                                    PRUint32 *_trust,
++                                    PRBool *_retval)
++{
++  // If an implementation chooses not to implement UI for displaying
++  // the cert and asking the user for confirmation,
++  // then this function must return PR_FALSE.
++  *_retval = PR_FALSE;
++  *_trust = nsIX509CertDB::UNTRUSTED;
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++EmbedCertificates::NotifyCACertExists(nsIInterfaceRequestor *ctx)
++{
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++EmbedCertificates::ChooseCertificate(
++  nsIInterfaceRequestor *ctx,
++  const PRUnichar *cn,
++  const PRUnichar *organization,
++  const PRUnichar *issuer,
++  const PRUnichar **certNickList,
++  const PRUnichar **certDetailsList,
++  PRUint32 count,
++  PRInt32 *selectedIndex,
++  PRBool *canceled)
++{
++  *canceled = PR_FALSE;
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++EmbedCertificates::PickCertificate(
++  nsIInterfaceRequestor *ctx,
++  const PRUnichar **certNickList,
++  const PRUnichar **certDetailsList,
++  PRUint32 count,
++  PRInt32 *selectedIndex,
++  PRBool *canceled)
++{
++  *canceled = PR_FALSE;
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++EmbedCertificates::SetPKCS12FilePassword(
++  nsIInterfaceRequestor *ctx,
++  nsAString &_password,
++  PRBool *_retval)
++{
++  /* The person who wrote this method implementation did
++   * not read the contract.
++   */
++  *_retval = PR_FALSE;
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++EmbedCertificates::GetPKCS12FilePassword(
++  nsIInterfaceRequestor *ctx,
++  nsAString &_password,
++  PRBool *_retval)
++{
++  /* The person who wrote this method implementation did
++   * not read the contract.
++   */
++  *_retval = PR_FALSE;
++  return NS_OK;
++}
++
++/* void viewCert (in nsIX509Cert cert); */
++NS_IMETHODIMP
++EmbedCertificates::ViewCert(
++  nsIInterfaceRequestor *ctx,
++  nsIX509Cert *cert)
++{
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++EmbedCertificates::DisplayGeneratingKeypairInfo(nsIInterfaceRequestor *aCtx, nsIKeygenThread *runnable)
++{
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++EmbedCertificates::ChooseToken(
++  nsIInterfaceRequestor *aCtx,
++  const PRUnichar **aTokenList,
++  PRUint32 aCount,
++  PRUnichar **aTokenChosen,
++  PRBool *aCanceled)
++{
++  *aCanceled = PR_FALSE;
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++EmbedCertificates::DisplayProtectedAuth(
++  nsIInterfaceRequestor *aCtx,
++  nsIProtectedAuthThread *runnable)
++{
++  return NS_OK;
++}
++
++/* boolean ConfirmKeyEscrow (in nsIX509Cert escrowAuthority); */
++NS_IMETHODIMP
++EmbedCertificates::ConfirmKeyEscrow(nsIX509Cert *escrowAuthority, PRBool *_retval)
++{
++  // If an implementation chooses not to implement UI that asks the user for 
++  // confirmation to hand out the private key, 
++  // then this function must return PR_FALSE.
++  *_retval = PR_FALSE;
++  return NS_OK;
++}
++
+diff --git a/embedding/browser/gtk/src/EmbedCertificates.h b/embedding/browser/gtk/src/EmbedCertificates.h
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/src/EmbedCertificates.h
+@@ -0,0 +1,84 @@
++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
++/* vim:set ts=2 sw=2 sts=2 et cindent: */
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * Netscape Communications Corporation.
++ * Portions created by the Initial Developer are Copyright (C) 2001
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *   Terry Hayes <[email protected]>
++ *   Javier Delgadillo <[email protected]>
++ *   Oleg Romashin <[email protected]>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++/**
++ * Derived from nsNSSDialogs http://landfill.mozilla.org/mxr-test/seamonkey/source/security/manager/pki/src/nsNSSDialogs.h
++ */
++#ifndef __EmbedCertificates_h
++#define __EmbedCertificates_h
++#include "nsITokenPasswordDialogs.h"
++#include "nsICertificateDialogs.h"
++#include "nsIClientAuthDialogs.h"
++#include "nsICertPickDialogs.h"
++#include "nsITokenDialogs.h"
++#include "nsIDOMCryptoDialogs.h"
++#include "nsIGenKeypairInfoDlg.h"
++#include "nsCOMPtr.h"
++#include "nsIStringBundle.h"
++#define EMBED_CERTIFICATES_CID \
++  { 0x518e071f, 0x1dd2, 0x11b2, \
++  { 0x93, 0x7e, 0xc4, 0x5f, 0x14, 0xde, 0xf7, 0x78 }}
++#define EMBED_CERTIFICATES_DESCRIPTION "Certificates Listener Impl"
++class EmbedPrivate;
++class EmbedCertificates
++: public nsITokenPasswordDialogs,
++  public nsICertificateDialogs,
++  public nsIClientAuthDialogs,
++  public nsICertPickDialogs,
++  public nsITokenDialogs,
++  public nsIDOMCryptoDialogs,
++  public nsIGeneratingKeypairInfoDialogs
++{
++  public:
++    NS_DECL_ISUPPORTS
++    NS_DECL_NSITOKENPASSWORDDIALOGS
++    NS_DECL_NSICERTIFICATEDIALOGS
++    NS_DECL_NSICLIENTAUTHDIALOGS
++    NS_DECL_NSICERTPICKDIALOGS
++    NS_DECL_NSITOKENDIALOGS
++    NS_DECL_NSIDOMCRYPTODIALOGS
++    NS_DECL_NSIGENERATINGKEYPAIRINFODIALOGS
++    EmbedCertificates();
++    virtual ~EmbedCertificates();
++    nsresult Init(void);
++  protected:
++  nsCOMPtr<nsIStringBundle> mPIPStringBundle;
++};
++#endif /* __EmbedCertificates_h */
+diff --git a/embedding/browser/gtk/src/EmbedContentListener.cpp b/embedding/browser/gtk/src/EmbedContentListener.cpp
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/src/EmbedContentListener.cpp
+@@ -0,0 +1,156 @@
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * Christopher Blizzard.
++ * Portions created by the Initial Developer are Copyright (C) 2001
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *   Christopher Blizzard <[email protected]>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#include "nsIURI.h"
++
++#include "EmbedContentListener.h"
++#include "EmbedPrivate.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(EmbedPrivate *aOwner)
++{
++  mOwner = aOwner;
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++EmbedContentListener::OnStartURIOpen(nsIURI     *aURI,
++				     PRBool     *aAbortOpen)
++{
++  nsresult rv;
++
++  nsCAutoString specString;
++  rv = aURI->GetSpec(specString);
++
++  if (NS_FAILED(rv))
++    return rv;
++
++  gint return_val = FALSE;
++  g_signal_emit(G_OBJECT(mOwner->mOwningWidget),
++                moz_embed_signals[OPEN_URI], 0,
++                specString.get(), &return_val);
++
++  *aAbortOpen = return_val;
++
++  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/embedding/browser/gtk/src/EmbedContentListener.h b/embedding/browser/gtk/src/EmbedContentListener.h
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/src/EmbedContentListener.h
+@@ -0,0 +1,66 @@
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * Christopher Blizzard.
++ * Portions created by the Initial Developer are Copyright (C) 2001
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *   Christopher Blizzard <[email protected]>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#ifndef __EmbedContentListener_h
++#define __EmbedContentListener_h
++
++#include "nsIURIContentListener.h"
++#include "nsWeakReference.h"
++
++class EmbedPrivate;
++
++class EmbedContentListener : public nsIURIContentListener,
++                             public nsSupportsWeakReference
++{
++ public:
++
++  EmbedContentListener();
++  virtual ~EmbedContentListener();
++
++  nsresult Init (EmbedPrivate *aOwner);
++
++  NS_DECL_ISUPPORTS
++
++  NS_DECL_NSIURICONTENTLISTENER
++
++ private:
++
++  EmbedPrivate *mOwner;
++  
++};
++
++#endif /* __EmbedContentListener_h */
+diff --git a/embedding/browser/gtk/src/EmbedContextMenuInfo.cpp b/embedding/browser/gtk/src/EmbedContextMenuInfo.cpp
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/src/EmbedContextMenuInfo.cpp
+@@ -0,0 +1,618 @@
++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
++/* vim:set ts=2 sw=2 sts=2 tw=80 et cindent: */
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * Oleg Romashin.
++ * Portions created by the Initial Developer are Copyright (C) 2006
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *   Oleg Romashin <[email protected]>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++#include "EmbedContextMenuInfo.h"
++#include "nsIImageLoadingContent.h"
++#include "imgILoader.h"
++#include "nsIDOMDocument.h"
++#include "nsIDOMHTMLDocument.h"
++#include "nsIDOMHTMLElement.h"
++#include "nsIDOMHTMLHtmlElement.h"
++#include "nsIDOMHTMLAnchorElement.h"
++#include "nsIDOMHTMLImageElement.h"
++#include "nsIDOMHTMLAreaElement.h"
++#include "nsIDOMHTMLLinkElement.h"
++#include "nsIDOMDocumentView.h"
++#include "nsIDOMAbstractView.h"
++#include "nsIDOMViewCSS.h"
++#include "nsIDOMCSSStyleDeclaration.h"
++#include "nsIDOMCSSValue.h"
++#include "nsIDOMCSSPrimitiveValue.h"
++#include "nsNetUtil.h"
++#include "nsUnicharUtils.h"
++#include "nsIDOMMouseEvent.h"
++#include "nsIDOMNSEvent.h"
++#include "nsIDOMWindow.h"
++#include "nsIDOMWindowCollection.h"
++#include "nsIWebBrowser.h"
++#include "nsIContent.h"
++#include "nsIPresShell.h"
++#include "nsIFormControl.h"
++#include "nsIDOMNSHTMLTextAreaElement.h"
++#include "nsIDOMHTMLInputElement.h"
++#include "nsIDOMHTMLTextAreaElement.h"
++#include "nsIDOMNSHTMLDocument.h"
++#include "nsIDOMNodeList.h"
++#include "nsISelection.h"
++#include "nsIDocument.h"
++#include "EmbedPrivate.h"
++#include <stdio.h>
++#include <stdarg.h>
++#include <stdlib.h>
++#include <glib.h>
++#if defined(FIXED_BUG347731) || !defined(MOZ_ENABLE_LIBXUL)
++#include "nsIFrame.h"
++#endif
++
++//*****************************************************************************
++// class EmbedContextMenuInfo
++//*****************************************************************************
++EmbedContextMenuInfo::EmbedContextMenuInfo(EmbedPrivate *aOwner) : mCtxFrameNum(-1), mEmbedCtxType(0)
++{
++  mOwner = aOwner;
++  mEventNode = nsnull;
++  mCtxDocument = nsnull;
++  mNSHHTMLElement = nsnull;
++  mNSHHTMLElementSc = nsnull;
++  mCtxEvent = nsnull;
++  mEventNode = nsnull;
++  mFormRect = nsIntRect(0,0,0,0);
++}
++
++EmbedContextMenuInfo::~EmbedContextMenuInfo(void)
++{
++  mEventNode = nsnull;
++  mCtxDocument = nsnull;
++  mNSHHTMLElement = nsnull;
++  mNSHHTMLElementSc = nsnull;
++  mCtxEvent = nsnull;
++  mEventNode = nsnull;
++}
++
++NS_IMPL_ADDREF(EmbedContextMenuInfo)
++NS_IMPL_RELEASE(EmbedContextMenuInfo)
++NS_INTERFACE_MAP_BEGIN(EmbedContextMenuInfo)
++NS_INTERFACE_MAP_ENTRY(nsISupports)
++NS_INTERFACE_MAP_END
++
++nsresult
++EmbedContextMenuInfo::SetFrameIndex()
++{
++  nsCOMPtr<nsIDOMWindowCollection> frames;
++  mCtxDomWindow->GetFrames(getter_AddRefs(frames));
++  nsCOMPtr<nsIDOMWindow> currentWindow;
++  PRUint32 frameCount = 0;
++  frames->GetLength(&frameCount);
++  for (unsigned int i= 0; i < frameCount; i++) {
++    frames->Item(i, getter_AddRefs(currentWindow));
++    nsCOMPtr<nsIDOMDocument> currentDoc;
++    currentWindow->GetDocument(getter_AddRefs(currentDoc));
++    if (currentDoc == mCtxDocument) {
++      mCtxFrameNum = i;
++      mCtxDomWindow = currentWindow;
++      nsCOMPtr<nsIDOMNSDocument> doc = do_QueryInterface(currentDoc);
++      if (doc)
++        doc->GetTitle(mCtxDocTitle);
++      return NS_OK;
++    }
++  }
++  return NS_ERROR_FAILURE;
++}
++
++nsresult
++EmbedContextMenuInfo::GetFormControlType(nsIDOMEvent* aEvent)
++{
++  if (!aEvent)
++    return NS_OK;
++  nsCOMPtr<nsIDOMNSEvent> nsevent(do_QueryInterface(aEvent));
++  nsCOMPtr<nsIDOMEventTarget> target;
++  nsevent->GetOriginalTarget(getter_AddRefs(target));
++  //    mOrigTarget  = target;
++  if (SetFormControlType(target)) {
++    nsCOMPtr<nsIDOMNode> eventNode = do_QueryInterface(target);
++    if (!eventNode)
++      return NS_OK;
++    //Frame Stuff
++    nsCOMPtr<nsIDOMDocument> domDoc;
++    nsresult rv = eventNode->GetOwnerDocument(getter_AddRefs(domDoc));
++    if (!NS_SUCCEEDED(rv) || !domDoc) {
++      return NS_OK;
++    }
++    mEventNode = eventNode;
++    mCtxDocument = domDoc;
++    nsCOMPtr<nsIDocument> doc = do_QueryInterface(mCtxDocument);
++    if (!doc)
++      return NS_OK;
++    nsIPresShell *presShell = doc->GetShell();
++    if (!presShell)
++      return NS_OK;
++    nsCOMPtr<nsIContent> tgContent = do_QueryInterface(mEventTarget);
++    nsIFrame* frame = nsnull;
++#if defined(FIXED_BUG347731) || !defined(MOZ_ENABLE_LIBXUL)
++    frame = tgContent->GetDocument() == presShell->GetDocument() ?
++      tgContent->GetPrimaryFrame() : nsnull;
++    if (frame)
++      mFormRect = frame->GetScreenRectExternal();
++#endif
++    return NS_OK;
++  }
++  return NS_ERROR_FAILURE;
++}
++
++nsresult
++EmbedContextMenuInfo::SetFormControlType(nsIDOMEventTarget *originalTarget)
++{
++  nsresult rv = NS_ERROR_FAILURE;
++  nsCOMPtr<nsIContent> targetContent = do_QueryInterface(originalTarget);
++  mCtxFormType = 0;
++  if (targetContent && targetContent->IsNodeOfType(nsIContent::eHTML_FORM_CONTROL)) {
++    nsCOMPtr<nsIFormControl> formControl(do_QueryInterface(targetContent));
++    if (formControl) {
++      mCtxFormType = formControl->GetType();
++      rv = NS_OK;
++      //#ifdef MOZ_LOGGING
++      switch (mCtxFormType) {
++      case NS_FORM_BUTTON_BUTTON:
++        break;
++      case NS_FORM_BUTTON_RESET:
++        break;
++      case NS_FORM_BUTTON_SUBMIT:
++        break;
++      case NS_FORM_INPUT_BUTTON:
++        break;
++      case NS_FORM_INPUT_CHECKBOX:
++        break;
++      case NS_FORM_INPUT_FILE:
++        mEmbedCtxType |= GTK_MOZ_EMBED_CTX_INPUT;
++        break;
++      case NS_FORM_INPUT_HIDDEN:
++        break;
++      case NS_FORM_INPUT_RESET:
++        break;
++      case NS_FORM_INPUT_IMAGE:
++        break;
++      case NS_FORM_INPUT_PASSWORD:
++        mEmbedCtxType |= GTK_MOZ_EMBED_CTX_INPUT;
++        mEmbedCtxType |= GTK_MOZ_EMBED_CTX_IPASSWORD;
++        break;
++      case NS_FORM_INPUT_RADIO:
++        break;
++      case NS_FORM_INPUT_SUBMIT:
++        break;
++      case NS_FORM_INPUT_EMAIL:
++      case NS_FORM_INPUT_SEARCH:
++      case NS_FORM_INPUT_TEXT:
++      case NS_FORM_INPUT_TEL:
++      case NS_FORM_INPUT_URL:
++        mEmbedCtxType |= GTK_MOZ_EMBED_CTX_INPUT;
++        break;
++      case NS_FORM_LABEL:
++        break;
++      case NS_FORM_SELECT:
++        break;
++      case NS_FORM_TEXTAREA:
++        mEmbedCtxType |= GTK_MOZ_EMBED_CTX_INPUT;
++        break;
++      case NS_FORM_OBJECT:
++        break;
++      case NS_FORM_OUTPUT:
++        break;
++      default:
++        break;
++      }
++      if (mEmbedCtxType & GTK_MOZ_EMBED_CTX_INPUT) {
++        PRBool rdonly = PR_FALSE;
++        if (mCtxFormType == NS_FORM_TEXTAREA) {
++          nsCOMPtr<nsIDOMHTMLTextAreaElement> input;
++          input = do_QueryInterface(mEventNode, &rv);
++          if (!NS_FAILED(rv) && input)
++            rv = input->GetReadOnly(&rdonly);
++          if (!NS_FAILED(rv) && rdonly) {
++            mEmbedCtxType |= GTK_MOZ_EMBED_CTX_ROINPUT;
++          }
++        } else {
++          nsCOMPtr<nsIDOMHTMLInputElement> input;
++          input = do_QueryInterface(mEventNode, &rv);
++          if (!NS_FAILED(rv) && input)
++            rv = input->GetReadOnly(&rdonly);
++          if (!NS_FAILED(rv) && rdonly) {
++            mEmbedCtxType |= GTK_MOZ_EMBED_CTX_ROINPUT;
++          }
++        }
++      }
++      //#endif
++    }
++  }
++  return rv;
++}
++
++const char*
++EmbedContextMenuInfo::GetSelectedText()
++{
++  nsString cString;
++  nsresult rv = NS_ERROR_FAILURE;
++  if (mCtxFormType != 0 && mEventNode) {
++    PRInt32 TextLength = 0, selStart = 0, selEnd = 0;
++    if (mCtxFormType == NS_FORM_INPUT_TEXT || mCtxFormType == NS_FORM_INPUT_FILE) {
++      nsCOMPtr<nsIDOMHTMLInputElement> nsinput = do_QueryInterface(mEventNode, &rv);
++      if (NS_SUCCEEDED(rv) && nsinput)
++        nsinput->GetTextLength(&TextLength);
++      if (TextLength > 0) {
++        nsinput->GetSelectionEnd(&selEnd);
++        nsinput->GetSelectionStart(&selStart);
++        if (selStart < selEnd || mCtxFormType == NS_FORM_INPUT_FILE) {
++          nsCOMPtr<nsIDOMHTMLInputElement> input = do_QueryInterface(mEventNode, &rv);
++          rv = input->GetValue(cString);
++        }
++      }
++    } else if (mCtxFormType == NS_FORM_TEXTAREA) {
++      nsCOMPtr<nsIDOMNSHTMLTextAreaElement> nsinput = do_QueryInterface(mEventNode, &rv);
++      if (NS_SUCCEEDED(rv) && nsinput)
++        nsinput->GetTextLength(&TextLength);
++      if (TextLength > 0) {
++        nsinput->GetSelectionStart(&selStart);
++        nsinput->GetSelectionEnd(&selEnd);
++        if (selStart < selEnd) {
++          nsCOMPtr<nsIDOMHTMLTextAreaElement> input = do_QueryInterface(mEventNode, &rv);
++          rv = input->GetValue(cString);
++        }
++      }
++    }
++    if (NS_SUCCEEDED(rv) && !cString.IsEmpty()) {
++      if (selStart < selEnd) {
++        cString.Cut(0, selStart);
++        cString.Cut(selEnd-selStart, TextLength);
++      }
++      rv = NS_OK;
++    }
++  } else if (mCtxDocument) {
++    nsCOMPtr<nsIDOMNSHTMLDocument> htmlDoc = do_QueryInterface(mCtxDocument, &rv);
++    if (NS_FAILED(rv) || !htmlDoc)
++      return nsnull;
++    rv = htmlDoc->GetSelection(cString);
++    if (NS_FAILED(rv) || cString.IsEmpty())
++      return nsnull;
++    rv = NS_OK;
++  }
++  if (rv == NS_OK) {
++    return NS_ConvertUTF16toUTF8(cString).get();
++  }
++  return nsnull;
++}
++
++nsresult
++EmbedContextMenuInfo::CheckDomImageElement(nsIDOMNode *node, nsString& aHref,
++                                           PRInt32 *aWidth, PRInt32 *aHeight)
++{
++  nsresult rv = NS_ERROR_FAILURE;
++  nsCOMPtr<nsIDOMHTMLImageElement> image =
++    do_QueryInterface(node, &rv);
++  if (image) {
++    rv = image->GetSrc(aHref);
++    if (NS_FAILED(rv)) {
++      return rv;
++    }
++    rv = image->GetWidth(aWidth);
++    rv = image->GetHeight(aHeight);
++    rv = NS_OK;
++  }
++  return rv;
++}
++
++nsresult
++EmbedContextMenuInfo::GetImageRequest(imgIRequest **aRequest, nsIDOMNode *aDOMNode)
++{
++  NS_ENSURE_ARG(aDOMNode);
++  NS_ENSURE_ARG_POINTER(aRequest);
++
++  // Get content
++  nsCOMPtr<nsIImageLoadingContent> content(do_QueryInterface(aDOMNode));
++  NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
++
++  return content->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
++                             aRequest);
++}
++
++nsresult
++EmbedContextMenuInfo::CheckDomHtmlNode(nsIDOMNode *aNode)
++{
++  nsresult rv = NS_ERROR_FAILURE;
++  nsString uTag;
++  PRUint16 dnode_type;
++
++  nsCOMPtr<nsIDOMNode> node;
++  if (!aNode && mEventNode)
++    node = mEventNode;
++  nsCOMPtr<nsIDOMHTMLElement> element  = do_QueryInterface(node, &rv);
++  if (!element) {
++    element = do_QueryInterface(mOrigNode, &rv);
++    if (element) {
++      node = mOrigNode;
++      element  = do_QueryInterface(node, &rv);
++    }
++  }
++
++  rv = node->GetNodeType(&dnode_type);
++  if (NS_FAILED(rv)) {
++    return rv;
++  }
++
++  if (!((nsIDOMNode::ELEMENT_NODE == dnode_type) && element)) {
++    return rv;
++  }
++  nsCOMPtr<nsIDOMNSHTMLElement> nodeElement = do_QueryInterface(node, &rv);
++  if (NS_SUCCEEDED(rv) && nodeElement) {
++    mNSHHTMLElement = nodeElement;
++  } else {
++    mNSHHTMLElement = nsnull;
++  }
++  rv = element->GetLocalName(uTag);
++  if (NS_FAILED(rv)) {
++    return rv;
++  }
++  if (uTag.LowerCaseEqualsLiteral("object")) {
++  }
++  else if (uTag.LowerCaseEqualsLiteral("html")) {
++  }
++  else if (uTag.LowerCaseEqualsLiteral("a")) {
++    nsCOMPtr<nsIDOMHTMLAnchorElement> anchor = do_QueryInterface(node);
++    anchor->GetHref(mCtxHref);
++    mEmbedCtxType |= GTK_MOZ_EMBED_CTX_LINK;
++    if (anchor && !mCtxHref.IsEmpty()) {
++      if (mCtxHref.LowerCaseEqualsLiteral("text/smartbookmark")) {
++        nsCOMPtr<nsIDOMNode> childNode;
++        node->GetFirstChild(getter_AddRefs(childNode));
++        if (childNode) {
++          PRInt32 width, height;
++          rv = CheckDomImageElement(node, mCtxImgHref, &width, &height);
++          if (NS_SUCCEEDED(rv))
++            mEmbedCtxType |= GTK_MOZ_EMBED_CTX_IMAGE;
++        }
++      } else if (StringBeginsWith(mCtxHref, NS_LITERAL_STRING("mailto:"))) {
++        mEmbedCtxType |= GTK_MOZ_EMBED_CTX_EMAIL;
++      }
++    }
++  }
++  else if (uTag.LowerCaseEqualsLiteral("area")) {
++    nsCOMPtr<nsIDOMHTMLAreaElement> area = do_QueryInterface(node, &rv);
++    if (NS_SUCCEEDED(rv) && area) {
++      PRBool aNoHref = PR_FALSE;
++      rv = area->GetNoHref(&aNoHref);
++      if (!aNoHref)
++        rv = area->GetHref(mCtxHref);
++      else
++        rv = area->GetTarget(mCtxHref);
++      mEmbedCtxType |= GTK_MOZ_EMBED_CTX_LINK;
++      rv = NS_OK;
++    }
++  }
++  else if (uTag.LowerCaseEqualsLiteral("img")) {
++    PRInt32 width, height;
++    rv = CheckDomImageElement(node, mCtxImgHref, &width, &height);
++    if (NS_SUCCEEDED(rv))
++      mEmbedCtxType |= GTK_MOZ_EMBED_CTX_IMAGE;
++  } else {
++    rv = NS_ERROR_FAILURE;
++  }
++  return rv;
++}
++
++nsresult
++EmbedContextMenuInfo::UpdateContextData(void *aEvent)
++{
++  NS_ENSURE_ARG_POINTER(aEvent);
++  nsresult rv;
++  nsCOMPtr<nsIDOMEvent> event = do_QueryInterface((nsISupports*)aEvent, &rv);
++  if (NS_FAILED(rv) || !event)
++    return NS_ERROR_FAILURE;
++  return UpdateContextData(event);
++}
++
++nsresult
++EmbedContextMenuInfo::GetElementForScroll(nsIDOMEvent *aEvent)
++{
++  if (!aEvent) return NS_ERROR_UNEXPECTED;
++  nsCOMPtr<nsIDOMNSEvent> nsevent(do_QueryInterface(aEvent));
++  nsCOMPtr<nsIDOMEventTarget> target;
++  nsevent->GetOriginalTarget(getter_AddRefs(target));
++  if (!target) return NS_ERROR_UNEXPECTED;
++  nsCOMPtr<nsIDOMNode> targetDOMNode(do_QueryInterface(target));
++  if (!targetDOMNode) return NS_ERROR_UNEXPECTED;
++  nsCOMPtr<nsIDOMDocument> targetDOMDocument;
++  targetDOMNode->GetOwnerDocument(getter_AddRefs(targetDOMDocument));
++  if (!targetDOMDocument) return NS_ERROR_UNEXPECTED;
++  return GetElementForScroll(targetDOMDocument);
++}
++
++nsresult
++EmbedContextMenuInfo::GetElementForScroll(nsIDOMDocument *targetDOMDocument)
++{
++  nsCOMPtr<nsIDOMElement> targetDOMElement;
++  targetDOMDocument->GetDocumentElement(getter_AddRefs(targetDOMElement));
++  if (!targetDOMElement) return NS_ERROR_UNEXPECTED;
++  nsString bodyName(NS_LITERAL_STRING("body"));
++  nsCOMPtr<nsIDOMNodeList> bodyList;
++  targetDOMElement->GetElementsByTagName(bodyName, getter_AddRefs(bodyList));
++  PRUint32 i = 0;
++  bodyList->GetLength(&i);
++  if (i) {
++    nsCOMPtr<nsIDOMNode> domBodyNode;
++    bodyList->Item(0, getter_AddRefs(domBodyNode));
++    if (!domBodyNode) return NS_ERROR_UNEXPECTED;
++    mNSHHTMLElementSc = do_QueryInterface(domBodyNode);
++    if (!mNSHHTMLElementSc) return NS_ERROR_UNEXPECTED;
++  }
++  return NS_OK;
++}
++
++nsresult
++EmbedContextMenuInfo::UpdateContextData(nsIDOMEvent *aDOMEvent)
++{
++  if (mCtxEvent == aDOMEvent)
++    return NS_OK;
++
++  nsresult rv = nsnull;
++  mCtxEvent = aDOMEvent;
++  NS_ENSURE_ARG_POINTER(mCtxEvent);
++
++  PRUint16 eventphase;
++  mCtxEvent->GetEventPhase(&eventphase);
++  if (!eventphase) {
++    mCtxEvent = nsnull;
++    return NS_ERROR_FAILURE;
++  }
++
++  nsCOMPtr<nsIDOMEventTarget> originalTarget = nsnull;
++  nsCOMPtr<nsIDOMNode> originalNode = nsnull;
++
++  nsCOMPtr<nsIDOMNSEvent> aEvent = do_QueryInterface(mCtxEvent, &rv);
++  if (NS_FAILED(rv) || !aEvent)
++    return NS_OK;
++
++  nsCOMPtr<nsIDOMMouseEvent> mouseEvent(do_QueryInterface(mCtxEvent, &rv));
++  if (mouseEvent) {
++    ((nsIDOMMouseEvent*)mouseEvent)->GetClientX(&mX);
++    ((nsIDOMMouseEvent*)mouseEvent)->GetClientY(&mY);
++  }
++
++  if (aEvent)
++    rv = aEvent->GetOriginalTarget(getter_AddRefs(originalTarget));
++  originalNode = do_QueryInterface(originalTarget);
++  if (NS_FAILED(rv) || !originalNode)
++    return NS_ERROR_NULL_POINTER;
++
++  //    nsresult SelText = mOwner->ClipBoardAction(GTK_MOZ_EMBED_CAN_COPY);
++  if (originalNode == mOrigNode)
++    return NS_OK;
++
++  mEmbedCtxType = GTK_MOZ_EMBED_CTX_NONE;
++  mOrigNode = originalNode;
++  if (mOrigNode) {
++    nsString SOrigNode;
++    mOrigNode->GetNodeName(SOrigNode);
++    if (SOrigNode.EqualsLiteral("#document"))
++      return NS_OK;
++    if (SOrigNode.EqualsLiteral("xul:thumb")
++        || SOrigNode.EqualsLiteral("xul:slider")
++        || SOrigNode.EqualsLiteral("xul:scrollbarbutton")
++        || SOrigNode.EqualsLiteral("xul:vbox")
++        || SOrigNode.EqualsLiteral("xul:spacer")) {
++      mEmbedCtxType |= GTK_MOZ_EMBED_CTX_XUL;
++      return NS_OK;
++    }
++  }
++  if (mCtxEvent)
++    rv = mCtxEvent->GetTarget(getter_AddRefs(mEventTarget));
++  if (NS_FAILED(rv) || !mEventTarget) {
++    return NS_OK;
++  }
++  nsCOMPtr<nsIDOMNode> eventNode = do_QueryInterface(mEventTarget, &rv);
++  mEventNode = eventNode;
++  //Frame Stuff
++  nsCOMPtr<nsIDOMDocument> domDoc;
++  if (mEventNode)
++    rv = mEventNode->GetOwnerDocument(getter_AddRefs(domDoc));
++  if (!NS_SUCCEEDED(rv) || !domDoc) {
++    //  return NS_OK;
++  }
++  if (NS_SUCCEEDED(rv) && domDoc && mCtxDocument != domDoc) {
++    mCtxDocument = domDoc;
++    mNSHHTMLElementSc = nsnull;
++    mCtxDocument->GetDocumentURI(mCtxURI);
++    NS_ENSURE_ARG_POINTER(mOwner);
++    nsCOMPtr<nsIWebBrowser> webBrowser;
++    mOwner->mWindow->GetWebBrowser(getter_AddRefs(webBrowser));
++    webBrowser->GetContentDOMWindow(getter_AddRefs(mCtxDomWindow));
++    nsCOMPtr<nsIDOMDocument> mainDocument;
++    mCtxDomWindow->GetDocument(getter_AddRefs(mainDocument));
++    if (!mainDocument) {
++      return NS_OK;
++    }
++    mCtxFrameNum = -1;
++    if (mainDocument != domDoc) {
++      mEmbedCtxType |= GTK_MOZ_EMBED_CTX_IFRAME;
++      SetFrameIndex();
++    }
++  }
++  nsCOMPtr<nsIDOMElement> targetDOMElement;
++  mCtxDocument->GetDocumentElement(getter_AddRefs(targetDOMElement));
++  if (!targetDOMElement) return NS_ERROR_UNEXPECTED;
++  nsCOMPtr<nsIDOMNSHTMLDocument> htmlDoc = do_QueryInterface(mCtxDocument);
++  if (htmlDoc) {
++    nsString DMode;
++    htmlDoc->GetDesignMode(DMode);
++    if (DMode.EqualsLiteral("on")) {
++      mEmbedCtxType |= GTK_MOZ_EMBED_CTX_INPUT;
++      mEmbedCtxType |= GTK_MOZ_EMBED_CTX_RICHEDIT;
++    }
++  }
++  nsCOMPtr<nsIDocument> doc = do_QueryInterface(mCtxDocument);
++  if (!doc)
++    return NS_OK;
++  nsIPresShell *presShell = doc->GetShell();
++  if (!presShell)
++    return NS_OK;
++  nsCOMPtr<nsIContent> tgContent = do_QueryInterface(mEventTarget);
++  nsIFrame* frame = nsnull;
++#if defined(FIXED_BUG347731) || !defined(MOZ_ENABLE_LIBXUL)
++  if (mEmbedCtxType & GTK_MOZ_EMBED_CTX_RICHEDIT)
++    frame = presShell->GetRootFrame();
++  else if (tgContent->GetDocument() == presShell->GetDocument()) {
++    frame = tgContent->GetPrimaryFrame();
++  }
++  if (frame) {
++    mFormRect = frame->GetScreenRectExternal();
++  }
++#endif
++  if (NS_SUCCEEDED(SetFormControlType(mEventTarget))) {
++    return NS_OK;
++  }
++  CheckDomHtmlNode();
++  nsCOMPtr<nsIDOMNode> node = mEventNode;
++  nsCOMPtr<nsIDOMNode> parentNode;
++  node->GetParentNode(getter_AddRefs(parentNode));
++  node = parentNode;
++  while (node) {
++    if (NS_FAILED(CheckDomHtmlNode()))
++      break;
++    node->GetParentNode(getter_AddRefs(parentNode));
++    node = parentNode;
++  }
++  mEmbedCtxType |= GTK_MOZ_EMBED_CTX_DOCUMENT;
++  return NS_OK;
++}
+diff --git a/embedding/browser/gtk/src/EmbedContextMenuInfo.h b/embedding/browser/gtk/src/EmbedContextMenuInfo.h
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/src/EmbedContextMenuInfo.h
+@@ -0,0 +1,101 @@
++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
++/* vim:set ts=2 sw=2 sts=2 tw=80 et cindent: */
++/*
++ * ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is the Mozilla browser.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * Oleg Romashin.
++ * Portions created by the Initial Developer are Copyright (C) 2006
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *   Oleg Romashin <[email protected]>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++#ifndef EmbedContextMenuInfo_h__
++#define EmbedContextMenuInfo_h__
++#include "nsCOMPtr.h"
++#include "nsIDOMNode.h"
++#include "nsIDOMEvent.h"
++#include "imgIContainer.h"
++#include "imgIRequest.h"
++#include "nsIDOMEventTarget.h"
++#include "nsRect.h"
++// for strings
++#ifdef MOZILLA_INTERNAL_API
++#include "nsXPIDLString.h"
++#include "nsReadableUtils.h"
++#endif
++#include "EmbedWindow.h"
++#include "nsIDOMNSHTMLElement.h"
++//*****************************************************************************
++// class EmbedContextMenuInfo
++//
++//*****************************************************************************
++class EmbedContextMenuInfo : public nsISupports
++{
++public:
++  EmbedContextMenuInfo(EmbedPrivate *aOwner);
++  virtual ~EmbedContextMenuInfo(void);
++  NS_DECL_ISUPPORTS
++  nsresult          GetFormControlType(nsIDOMEvent *aDOMEvent);
++  nsresult          UpdateContextData(nsIDOMEvent *aDOMEvent);
++  nsresult          UpdateContextData(void *aEvent);
++  const char*       GetSelectedText();
++  nsresult          GetElementForScroll(nsIDOMDocument *targetDOMDocument);
++  nsresult          GetElementForScroll(nsIDOMEvent *aEvent);
++  nsresult          CheckDomImageElement(nsIDOMNode *node, nsString& aHref,
++                                       PRInt32 *aWidth, PRInt32 *aHeight);
++  nsresult          GetImageRequest(imgIRequest **aRequest, nsIDOMNode *aDOMNode);
++  nsString          GetCtxDocTitle(void) { return mCtxDocTitle; }
++
++
++  PRInt32                 mX, mY, mObjWidth, mObjHeight, mCtxFrameNum;
++  nsString                mCtxURI, mCtxHref, mCtxImgHref;
++  PRUint32                mEmbedCtxType;
++  PRInt32 mCtxFormType;
++  nsCOMPtr<nsIDOMNode>    mEventNode;
++  nsCOMPtr<nsIDOMEventTarget> mEventTarget;
++  nsCOMPtr<nsIDOMDocument>mCtxDocument;
++  nsIntRect               mFormRect;
++  nsCOMPtr<nsIDOMWindow>  mCtxDomWindow;
++  nsCOMPtr<nsIDOMEvent>   mCtxEvent;
++  nsCOMPtr<nsIDOMNSHTMLElement> mNSHHTMLElement;
++  nsCOMPtr<nsIDOMNSHTMLElement> mNSHHTMLElementSc;
++private:
++  nsresult          SetFrameIndex();
++  nsresult          SetFormControlType(nsIDOMEventTarget *originalTarget);
++  nsresult          CheckDomHtmlNode(nsIDOMNode *aNode = nsnull);
++
++  EmbedPrivate           *mOwner;
++  nsCOMPtr<nsIDOMNode>    mOrigNode;
++  nsString                mCtxDocTitle;
++}; // class EmbedContextMenuInfo
++#endif // EmbedContextMenuInfo_h__
+diff --git a/embedding/browser/gtk/src/EmbedEventListener.cpp b/embedding/browser/gtk/src/EmbedEventListener.cpp
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/src/EmbedEventListener.cpp
+@@ -0,0 +1,304 @@
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * Christopher Blizzard.
++ * Portions created by the Initial Developer are Copyright (C) 2001
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *   Christopher Blizzard <[email protected]>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#include "nsCOMPtr.h"
++#include "nsIDOMMouseEvent.h"
++
++#include "nsIDOMKeyEvent.h"
++#include "nsIDOMUIEvent.h"
++
++#include "EmbedEventListener.h"
++#include "EmbedPrivate.h"
++
++EmbedEventListener::EmbedEventListener(void)
++{
++  mOwner = nsnull;
++}
++
++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_END
++
++nsresult
++EmbedEventListener::Init(EmbedPrivate *aOwner)
++{
++  mOwner = aOwner;
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++EmbedEventListener::HandleEvent(nsIDOMEvent* aDOMEvent)
++{
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++EmbedEventListener::KeyDown(nsIDOMEvent* aDOMEvent)
++{
++  nsCOMPtr <nsIDOMKeyEvent> keyEvent;
++  keyEvent = do_QueryInterface(aDOMEvent);
++  if (!keyEvent)
++    return NS_OK;
++  // Return FALSE to this function to mark the event as not
++  // consumed...
++  gint return_val = FALSE;
++  g_signal_emit(G_OBJECT(mOwner->mOwningWidget),
++                moz_embed_signals[DOM_KEY_DOWN], 0,
++                (void *)keyEvent, &return_val);
++  if (return_val) {
++    aDOMEvent->StopPropagation();
++    aDOMEvent->PreventDefault();
++  }
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++EmbedEventListener::KeyUp(nsIDOMEvent* aDOMEvent)
++{
++  nsCOMPtr <nsIDOMKeyEvent> keyEvent;
++  keyEvent = do_QueryInterface(aDOMEvent);
++  if (!keyEvent)
++    return NS_OK;
++  // return FALSE to this function to mark this event as not
++  // consumed...
++  gint return_val = FALSE;
++  g_signal_emit(G_OBJECT(mOwner->mOwningWidget),
++                moz_embed_signals[DOM_KEY_UP], 0,
++                (void *)keyEvent, &return_val);
++  if (return_val) {
++    aDOMEvent->StopPropagation();
++    aDOMEvent->PreventDefault();
++  }
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++EmbedEventListener::KeyPress(nsIDOMEvent* aDOMEvent)
++{
++  nsCOMPtr <nsIDOMKeyEvent> keyEvent;
++  keyEvent = do_QueryInterface(aDOMEvent);
++  if (!keyEvent)
++    return NS_OK;
++  // Return TRUE from your signal handler to mark the event as consumed.
++  gint return_val = FALSE;
++  g_signal_emit(G_OBJECT(mOwner->mOwningWidget),
++                moz_embed_signals[DOM_KEY_PRESS], 0,
++                (void *)keyEvent, &return_val);
++  if (return_val) {
++    aDOMEvent->StopPropagation();
++    aDOMEvent->PreventDefault();
++  }
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++EmbedEventListener::MouseDown(nsIDOMEvent* aDOMEvent)
++{
++  nsCOMPtr <nsIDOMMouseEvent> mouseEvent;
++  mouseEvent = do_QueryInterface(aDOMEvent);
++  if (!mouseEvent)
++    return NS_OK;
++  // Return TRUE from your signal handler to mark the event as consumed.
++  gint return_val = FALSE;
++  g_signal_emit(G_OBJECT(mOwner->mOwningWidget),
++                moz_embed_signals[DOM_MOUSE_DOWN], 0,
++                (void *)mouseEvent, &return_val);
++  if (return_val) {
++    aDOMEvent->StopPropagation();
++    aDOMEvent->PreventDefault();
++  }
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++EmbedEventListener::MouseUp(nsIDOMEvent* aDOMEvent)
++{
++  nsCOMPtr <nsIDOMMouseEvent> mouseEvent;
++  mouseEvent = do_QueryInterface(aDOMEvent);
++  if (!mouseEvent)
++    return NS_OK;
++  // Return TRUE from your signal handler to mark the event as consumed.
++  gint return_val = FALSE;
++  g_signal_emit(G_OBJECT(mOwner->mOwningWidget),
++                moz_embed_signals[DOM_MOUSE_UP], 0,
++                (void *)mouseEvent, &return_val);
++  if (return_val) {
++    aDOMEvent->StopPropagation();
++    aDOMEvent->PreventDefault();
++  }
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++EmbedEventListener::MouseClick(nsIDOMEvent* aDOMEvent)
++{
++  nsCOMPtr <nsIDOMMouseEvent> mouseEvent;
++  mouseEvent = do_QueryInterface(aDOMEvent);
++  if (!mouseEvent)
++    return NS_OK;
++  // Return TRUE from your signal handler to mark the event as consumed.
++  gint return_val = FALSE;
++  g_signal_emit(G_OBJECT(mOwner->mOwningWidget),
++                moz_embed_signals[DOM_MOUSE_CLICK], 0,
++                (void *)mouseEvent, &return_val);
++  if (return_val) {
++    aDOMEvent->StopPropagation();
++    aDOMEvent->PreventDefault();
++  }
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++EmbedEventListener::MouseDblClick(nsIDOMEvent* aDOMEvent)
++{
++  nsCOMPtr <nsIDOMMouseEvent> mouseEvent;
++  mouseEvent = do_QueryInterface(aDOMEvent);
++  if (!mouseEvent)
++    return NS_OK;
++  // Return TRUE from your signal handler to mark the event as consumed.
++  gint return_val = FALSE;
++  g_signal_emit(G_OBJECT(mOwner->mOwningWidget),
++                moz_embed_signals[DOM_MOUSE_DBL_CLICK], 0,
++                (void *)mouseEvent, &return_val);
++  if (return_val) {
++    aDOMEvent->StopPropagation();
++    aDOMEvent->PreventDefault();
++  }
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++EmbedEventListener::MouseOver(nsIDOMEvent* aDOMEvent)
++{
++  nsCOMPtr <nsIDOMMouseEvent> mouseEvent;
++  mouseEvent = do_QueryInterface(aDOMEvent);
++  if (!mouseEvent)
++    return NS_OK;
++  // Return TRUE from your signal handler to mark the event as consumed.
++  gint return_val = FALSE;
++  g_signal_emit(G_OBJECT(mOwner->mOwningWidget),
++                moz_embed_signals[DOM_MOUSE_OVER], 0,
++                (void *)mouseEvent, &return_val);
++  if (return_val) {
++    aDOMEvent->StopPropagation();
++    aDOMEvent->PreventDefault();
++  }
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++EmbedEventListener::MouseOut(nsIDOMEvent* aDOMEvent)
++{
++  nsCOMPtr <nsIDOMMouseEvent> mouseEvent;
++  mouseEvent = do_QueryInterface(aDOMEvent);
++  if (!mouseEvent)
++    return NS_OK;
++  // Return TRUE from your signal handler to mark the event as consumed.
++  gint return_val = FALSE;
++  g_signal_emit(G_OBJECT(mOwner->mOwningWidget),
++                moz_embed_signals[DOM_MOUSE_OUT], 0,
++                (void *)mouseEvent, &return_val);
++  if (return_val) {
++    aDOMEvent->StopPropagation();
++    aDOMEvent->PreventDefault();
++  }
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++EmbedEventListener::Activate(nsIDOMEvent* aDOMEvent)
++{
++  nsCOMPtr <nsIDOMUIEvent> uiEvent = do_QueryInterface(aDOMEvent);
++  if (!uiEvent)
++    return NS_OK;
++  // Return TRUE from your signal handler to mark the event as consumed.
++  gint return_val = FALSE;
++  g_signal_emit(G_OBJECT(mOwner->mOwningWidget),
++                moz_embed_signals[DOM_ACTIVATE], 0,
++                (void *)uiEvent, &return_val);
++  if (return_val) {
++    aDOMEvent->StopPropagation();
++    aDOMEvent->PreventDefault();
++  }
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++EmbedEventListener::FocusIn(nsIDOMEvent* aDOMEvent)
++{
++  nsCOMPtr <nsIDOMUIEvent> uiEvent = do_QueryInterface(aDOMEvent);
++  if (!uiEvent)
++    return NS_OK;
++  // Return TRUE from your signal handler to mark the event as consumed.
++  gint return_val = FALSE;
++  g_signal_emit(G_OBJECT(mOwner->mOwningWidget),
++                moz_embed_signals[DOM_FOCUS_IN], 0,
++                (void *)uiEvent, &return_val);
++  if (return_val) {
++    aDOMEvent->StopPropagation();
++    aDOMEvent->PreventDefault();
++  }
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++EmbedEventListener::FocusOut(nsIDOMEvent* aDOMEvent)
++{
++  nsCOMPtr <nsIDOMUIEvent> uiEvent = do_QueryInterface(aDOMEvent);
++  if (!uiEvent)
++    return NS_OK;
++  // Return TRUE from your signal handler to mark the event as consumed.
++  gint return_val = FALSE;
++  g_signal_emit(G_OBJECT(mOwner->mOwningWidget),
++                moz_embed_signals[DOM_FOCUS_OUT], 0,
++                (void *)uiEvent, &return_val);
++  if (return_val) {
++    aDOMEvent->StopPropagation();
++    aDOMEvent->PreventDefault();
++  }
++  return NS_OK;
++}
+diff --git a/embedding/browser/gtk/src/EmbedEventListener.h b/embedding/browser/gtk/src/EmbedEventListener.h
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/src/EmbedEventListener.h
+@@ -0,0 +1,90 @@
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * Christopher Blizzard.
++ * Portions created by the Initial Developer are Copyright (C) 2001
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *   Christopher Blizzard <[email protected]>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#ifndef __EmbedEventListener_h
++#define __EmbedEventListener_h
++
++#include "nsIDOMKeyListener.h"
++#include "nsIDOMMouseListener.h"
++#include "nsIDOMUIListener.h"
++
++class EmbedPrivate;
++
++class EmbedEventListener : public nsIDOMKeyListener,
++                           public nsIDOMMouseListener,
++                           public nsIDOMUIListener
++{
++ public:
++
++  EmbedEventListener();
++  virtual ~EmbedEventListener();
++
++  nsresult Init(EmbedPrivate *aOwner);
++
++  NS_DECL_ISUPPORTS
++
++  // nsIDOMEventListener
++
++  NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
++
++  // 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);
++
++ private:
++
++  EmbedPrivate *mOwner;
++};
++
++#endif /* __EmbedEventListener_h */
+diff --git a/embedding/browser/gtk/src/EmbedGtkTools.cpp b/embedding/browser/gtk/src/EmbedGtkTools.cpp
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/src/EmbedGtkTools.cpp
+@@ -0,0 +1,88 @@
++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
++/* vim:set ts=2 sw=4 sts=2 tw=80 et cindent: */
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * Oleg Romashin.
++ * Portions created by the Initial Developer are Copyright (C) 2006
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *   Oleg Romashin <[email protected]>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#include "EmbedGtkTools.h"
++#ifndef MOZILLA_INTERNAL_API
++#include "nsServiceManagerUtils.h"
++#endif
++#include "EmbedPrivate.h"
++
++GtkWidget * GetGtkWidgetForDOMWindow(nsIDOMWindow* aDOMWindow)
++{
++  nsCOMPtr<nsIWindowWatcher> wwatch = do_GetService("@mozilla.org/embedcomp/window-watcher;1");
++  if (!aDOMWindow)
++    return NULL;
++  nsCOMPtr<nsIWebBrowserChrome> chrome;
++  wwatch->GetChromeForWindow(aDOMWindow, getter_AddRefs(chrome));
++  if (!chrome) {
++    return GTK_WIDGET(EmbedCommon::GetAnyLiveWidget());
++  }
++
++  nsCOMPtr<nsIEmbeddingSiteWindow> siteWindow = nsnull;
++  siteWindow = do_QueryInterface(chrome);
++
++  if (!siteWindow) {
++    return GTK_WIDGET(EmbedCommon::GetAnyLiveWidget());
++  }
++
++  GtkWidget* parentWidget;
++  siteWindow->GetSiteWindow((void**)&parentWidget);
++  if (GTK_IS_WIDGET(parentWidget))
++    return parentWidget;
++  return NULL;
++}
++
++GtkWindow * GetGtkWindowForDOMWindow(nsIDOMWindow* aDOMWindow)
++{
++  GtkWidget* parentWidget = GetGtkWidgetForDOMWindow(aDOMWindow);
++  if (!parentWidget)
++    return NULL;
++  GtkWidget* gtkWin = gtk_widget_get_toplevel(parentWidget);
++  if (GTK_WIDGET_TOPLEVEL(gtkWin))
++    return GTK_WINDOW(gtkWin);
++  return NULL;
++}
++
++nsresult GetContentViewer(nsIWebBrowser *webBrowser, nsIContentViewer **aViewer)
++{
++  g_return_val_if_fail(webBrowser, NS_ERROR_FAILURE);
++  nsCOMPtr<nsIDocShell> docShell(do_GetInterface((nsISupports*)webBrowser));
++  NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
++  return docShell->GetContentViewer(aViewer);
++}
+diff --git a/embedding/browser/gtk/src/EmbedGtkTools.h b/embedding/browser/gtk/src/EmbedGtkTools.h
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/src/EmbedGtkTools.h
+@@ -0,0 +1,67 @@
++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
++/* vim:set ts=2 sw=2 sts=2 et cindent: */
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * Oleg Romashin.
++ * Portions created by the Initial Developer are Copyright (C) 2006
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *   Oleg Romashin <[email protected]>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++#ifndef __EmbedTools_h
++#define __EmbedTools_h
++
++#include "nsCOMPtr.h"
++#ifdef MOZILLA_INTERNAL_API
++#include "nsString.h"
++#else
++#include "nsStringAPI.h"
++#endif
++#include "nsIDOMWindow.h"
++#include "nsIWindowWatcher.h"
++#include "nsIWebBrowserChrome.h"
++#include "nsIEmbeddingSiteWindow.h"
++#include "nsIServiceManager.h"
++#include "nsIContentViewer.h"
++#include "nsIDocShell.h"
++#include "nsIInterfaceRequestorUtils.h"
++#include <gtk/gtk.h>
++
++GtkWidget*
++GetGtkWidgetForDOMWindow(nsIDOMWindow* aDOMWindow);
++
++GtkWindow*
++GetGtkWindowForDOMWindow(nsIDOMWindow* aDOMWindow);
++
++nsresult
++GetContentViewer(nsIWebBrowser *webBrowser, nsIContentViewer **aViewer);
++
++#endif /* __EmbedTools_h */
+diff --git a/embedding/browser/gtk/src/EmbedPrivate.cpp b/embedding/browser/gtk/src/EmbedPrivate.cpp
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/src/EmbedPrivate.cpp
+@@ -0,0 +1,983 @@
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * Christopher Blizzard.
++ * Portions created by the Initial Developer are Copyright (C) 2001
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *   Christopher Blizzard <[email protected]>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#include "nsIDocShell.h"
++#include "nsIWebProgress.h"
++#include "nsIWidget.h"
++#include "nsCRT.h"
++#include "nsNetUtil.h"
++#include "nsIWebBrowserStream.h"
++#include "nsIWebBrowserFocus.h"
++#include "nsIDirectoryService.h"
++#include "nsAppDirectoryServiceDefs.h"
++
++// for do_GetInterface
++#include "nsIInterfaceRequestor.h"
++// for do_CreateInstance
++#include "nsIComponentManager.h"
++#include "nsComponentManagerUtils.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"
++
++// all of our local includes
++#include "EmbedPrivate.h"
++#include "EmbedWindow.h"
++#include "EmbedProgress.h"
++#include "EmbedContentListener.h"
++#include "EmbedEventListener.h"
++#include "EmbedWindowCreator.h"
++#include "GtkPromptService.h"
++
++#include "mozilla/ModuleUtils.h"
++
++#ifdef MOZ_ACCESSIBILITY_ATK
++#include "nsIAccessibilityService.h"
++#include "nsIAccessible.h"
++#include "nsIDOMDocument.h"
++#endif
++
++PRUint32                 EmbedPrivate::sWidgetCount = 0;
++
++char                    *EmbedPrivate::sPath        = nsnull;
++char                    *EmbedPrivate::sCompPath    = nsnull;
++nsTArray<EmbedPrivate*> *EmbedPrivate::sWindowList  = nsnull;
++nsILocalFile            *EmbedPrivate::sProfileDir  = nsnull;
++nsISupports             *EmbedPrivate::sProfileLock = nsnull;
++GtkWidget               *EmbedPrivate::sOffscreenWindow = 0;
++GtkWidget               *EmbedPrivate::sOffscreenFixed  = 0;
++
++nsIDirectoryServiceProvider *EmbedPrivate::sAppFileLocProvider = nsnull;
++
++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 1;
++}
++
++NS_IMETHODIMP_(nsrefcnt)
++GTKEmbedDirectoryProvider::Release()
++{
++  return 1;
++}
++
++NS_IMETHODIMP
++GTKEmbedDirectoryProvider::GetFile(const char *aKey, PRBool *aPersist,
++                                   nsIFile* *aResult)
++{
++  if (EmbedPrivate::sAppFileLocProvider) {
++    nsresult rv = EmbedPrivate::sAppFileLocProvider->GetFile(aKey, aPersist,
++                                                             aResult);
++    if (NS_SUCCEEDED(rv))
++      return rv;
++  }
++
++  if (EmbedPrivate::sProfileDir && (!strcmp(aKey, NS_APP_USER_PROFILE_50_DIR)
++                                 || !strcmp(aKey, NS_APP_PROFILE_DIR_STARTUP))) {
++    *aPersist = PR_TRUE;
++    return EmbedPrivate::sProfileDir->Clone(aResult);
++  }
++
++  return NS_ERROR_FAILURE;
++}
++
++NS_IMETHODIMP
++GTKEmbedDirectoryProvider::GetFiles(const char *aKey,
++                                    nsISimpleEnumerator* *aResult)
++{
++  nsCOMPtr<nsIDirectoryServiceProvider2>
++    dp2(do_QueryInterface(EmbedPrivate::sAppFileLocProvider));
++
++  if (!dp2)
++    return NS_ERROR_FAILURE;
++
++  return dp2->GetFiles(aKey, aResult);
++}
++
++#define NS_PROMPTSERVICE_CID \
++ {0x95611356, 0xf583, 0x46f5, {0x81, 0xff, 0x4b, 0x3e, 0x01, 0x62, 0xc6, 0x19}}
++
++NS_GENERIC_FACTORY_CONSTRUCTOR(GtkPromptService)
++NS_DEFINE_NAMED_CID(NS_PROMPTSERVICE_CID);
++
++static const mozilla::Module::CIDEntry kDefaultPromptCIDs[] = {
++  { &kNS_PROMPTSERVICE_CID, false, NULL, GtkPromptServiceConstructor },
++  { NULL }
++};
++
++static const mozilla::Module::ContractIDEntry kDefaultPromptContracts[] = {
++  { "@mozilla.org/embedcomp/prompt-service;1", &kNS_PROMPTSERVICE_CID },
++  { NULL }
++};
++
++static const mozilla::Module kDefaultPromptModule = {
++  mozilla::Module::kVersion,
++  kDefaultPromptCIDs,
++  kDefaultPromptContracts
++};
++
++EmbedPrivate::EmbedPrivate(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  = 0;
++  mIsDestroyed      = PR_FALSE;
++
++  PushStartup();
++  if (!sWindowList) {
++    sWindowList = new nsTArray<EmbedPrivate*>();
++  }
++  sWindowList->AppendElement(this);
++}
++
++EmbedPrivate::~EmbedPrivate()
++{
++  sWindowList->RemoveElement(this);
++  PopStartup();
++}
++
++nsresult
++EmbedPrivate::Init(GtkMozEmbed *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();
++  mEventListenerGuard =
++    static_cast<nsISupports *>(static_cast<nsIDOMKeyListener *>(mEventListener));
++  mEventListener->Init(this);
++
++  // has the window creator service been set up?
++  static int initialized = PR_FALSE;
++  // Set up our window creator ( only once )
++  if (!initialized) {
++    // We set this flag here instead of on success.  If it failed we
++    // don't want to keep trying and leaking window creator objects.
++    initialized = PR_TRUE;
++
++    // create our local object
++    EmbedWindowCreator *creator = new EmbedWindowCreator();
++    nsCOMPtr<nsIWindowCreator> windowCreator;
++    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 NS_OK;
++}
++
++nsresult
++EmbedPrivate::Realize(PRBool *aAlreadyRealized)
++{
++
++  *aAlreadyRealized = PR_FALSE;
++
++  // create the offscreen window if we have to
++  EnsureOffscreenWindow();
++
++  // 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.
++  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
++EmbedPrivate::Unrealize(void)
++{
++  // reparent to our offscreen window
++  gtk_widget_reparent(mMozWindowWidget, sOffscreenFixed);
++}
++
++void
++EmbedPrivate::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
++EmbedPrivate::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
++EmbedPrivate::Resize(PRUint32 aWidth, PRUint32 aHeight)
++{
++  mWindow->SetDimensions(nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION |
++			 nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_INNER,
++			 0, 0, aWidth, aHeight);
++}
++
++void
++EmbedPrivate::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;
++  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();
++  if (mEventTarget)
++    mEventTarget = nsnull;
++
++  // destroy our child window
++  mWindow->ReleaseChildren();
++
++  // release navigation
++  mNavigation = nsnull;
++
++  // release session history
++  mSessionHistory = nsnull;
++
++  mOwningWidget = nsnull;
++
++  mMozWindowWidget = 0;
++}
++
++void
++EmbedPrivate::SetURI(const char *aURI)
++{
++  mURI.Assign(aURI);
++}
++
++void
++EmbedPrivate::LoadCurrentURI(void)
++{
++  if (mURI.Length()) {
++    nsCOMPtr<nsPIDOMWindow> piWin;
++    GetPIDOMWindow(getter_AddRefs(piWin));
++
++    nsAutoPopupStatePusher popupStatePusher(piWin, openAllowed);
++
++    mNavigation->LoadURI(NS_ConvertUTF8toUTF16(mURI).get(), // URI string
++                         nsIWebNavigation::LOAD_FLAGS_NONE | // Load flags
++                         nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP,  // Allow keyword.URL.. functionality
++                         nsnull,                            // Referring URI
++                         nsnull,                            // Post data
++                         nsnull);                           // extra headers
++  }
++}
++
++void
++EmbedPrivate::Reload(PRUint32 reloadFlags)
++{
++  /* Use the session history if it is available, this
++   * allows framesets to reload correctly */
++  nsCOMPtr<nsIWebNavigation> wn;
++
++  if (mSessionHistory) {
++    wn = do_QueryInterface(mSessionHistory);
++  }
++  if (!wn)
++    wn = mNavigation;
++
++  if (wn)
++    wn->Reload(reloadFlags);
++}
++
++
++void
++EmbedPrivate::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
++EmbedPrivate::SetChromeMask(PRUint32 aChromeMask)
++{
++   mChromeMask = aChromeMask;
++
++   ApplyChromeMask();
++}
++
++
++/* static */
++void
++EmbedPrivate::PushStartup(void)
++{
++  // increment the number of widgets
++  sWidgetCount++;
++
++  // if this is the first widget, fire up xpcom
++  if (sWidgetCount == 1) {
++    nsresult rv;
++
++    nsCOMPtr<nsILocalFile> binDir;
++    if (sCompPath) {
++      rv = NS_NewNativeLocalFile(nsDependentCString(sCompPath), 1, getter_AddRefs(binDir));
++      if (NS_FAILED(rv))
++	return;
++    }
++
++    const char *grePath = sPath;
++
++    if (!grePath)
++      grePath = getenv("MOZILLA_FIVE_HOME");
++
++    if (!grePath)
++      return;
++
++    nsCOMPtr<nsILocalFile> greDir;
++    rv = NS_NewNativeLocalFile(nsDependentCString(grePath), PR_TRUE,
++                               getter_AddRefs(greDir));
++    if (NS_FAILED(rv))
++      return;
++
++    if (sProfileDir && !sProfileLock) {
++      rv = XRE_LockProfileDirectory(sProfileDir,
++                                    &sProfileLock);
++      if (NS_FAILED(rv)) return;
++    }
++
++    rv = XRE_InitEmbedding2(greDir, binDir,
++                            const_cast<GTKEmbedDirectoryProvider*>(&kDirectoryProvider));
++    if (NS_FAILED(rv))
++      return;
++
++    if (sProfileDir)
++      XRE_NotifyProfile();
++
++    RegisterAppComponents();
++  }
++}
++
++/* static */
++void
++EmbedPrivate::PopStartup(void)
++{
++  sWidgetCount--;
++  if (sWidgetCount == 0) {
++
++    // destroy the offscreen window
++    DestroyOffscreenWindow();
++
++    // we no longer need a reference to the DirectoryServiceProvider
++    if (sAppFileLocProvider) {
++      NS_RELEASE(sAppFileLocProvider);
++      sAppFileLocProvider = nsnull;
++    }
++
++    // shut down XPCOM/Embedding
++    XRE_TermEmbedding();
++
++    NS_IF_RELEASE(sProfileLock);
++    NS_IF_RELEASE(sProfileDir);
++  }
++}
++
++/* static */
++void EmbedPrivate::SetPath(const char *aPath)
++{
++  if (sPath)
++    free(sPath);
++  if (aPath)
++    sPath = strdup(aPath);
++  else
++    sPath = nsnull;
++}
++
++/* static */
++void
++EmbedPrivate::SetCompPath(const char *aPath)
++{
++  if (sCompPath)
++    free(sCompPath);
++  if (aPath)
++    sCompPath = strdup(aPath);
++  else
++    sCompPath = nsnull;
++}
++
++/* static */
++void
++EmbedPrivate::SetProfilePath(const char *aDir, const char *aName)
++{
++  if (sProfileDir) {
++    if (sWidgetCount) {
++      NS_ERROR("Cannot change profile directory during run.");
++      return;
++    }
++
++    NS_RELEASE(sProfileDir);
++    NS_RELEASE(sProfileLock);
++  }
++
++  nsresult rv =
++    NS_NewNativeLocalFile(nsDependentCString(aDir), PR_TRUE, &sProfileDir);
++
++  if (NS_SUCCEEDED(rv) && aName)
++    rv = sProfileDir->AppendNative(nsDependentCString(aName));
++
++  if (NS_SUCCEEDED(rv)) {
++    PRBool exists = PR_FALSE;
++    rv = sProfileDir->Exists(&exists);
++    if (!exists)
++      rv = sProfileDir->Create(nsIFile::DIRECTORY_TYPE, 0700);
++    rv = XRE_LockProfileDirectory(sProfileDir, &sProfileLock);
++  }
++
++  if (NS_SUCCEEDED(rv)) {
++    if (sWidgetCount)
++      XRE_NotifyProfile();
++
++    return;
++  }
++
++  NS_WARNING("Failed to lock profile.");
++
++  // Failed
++  NS_IF_RELEASE(sProfileDir);
++  NS_IF_RELEASE(sProfileLock);
++}
++
++void
++EmbedPrivate::SetDirectoryServiceProvider(nsIDirectoryServiceProvider * appFileLocProvider)
++{
++  if (sAppFileLocProvider)
++    NS_RELEASE(sAppFileLocProvider);
++
++  if (appFileLocProvider) {
++    sAppFileLocProvider = appFileLocProvider;
++    NS_ADDREF(sAppFileLocProvider);
++  }
++}
++
++nsresult
++EmbedPrivate::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;
++
++  nsCOMPtr<nsIURI> uri;
++  nsresult rv = NS_NewURI(getter_AddRefs(uri), aBaseURI);
++  if (NS_FAILED(rv))
++    return rv;
++
++  rv = wbStream->OpenStream(uri, nsDependentCString(aContentType));
++  return rv;
++}
++
++nsresult
++EmbedPrivate::AppendToStream(const PRUint8 *aData, PRUint32 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
++EmbedPrivate::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();
++}
++
++/* static */
++EmbedPrivate *
++EmbedPrivate::FindPrivateForBrowser(nsIWebBrowserChrome *aBrowser)
++{
++  if (!sWindowList)
++    return nsnull;
++
++  // Get the number of browser windows.
++  PRInt32 count = sWindowList->Length();
++  // 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 (int i = 0; i < count; i++) {
++    EmbedPrivate *tmpPrivate = sWindowList->ElementAt(i);
++    // get the browser object for that window
++    nsIWebBrowserChrome *chrome = static_cast<nsIWebBrowserChrome *>(
++						 tmpPrivate->mWindow);
++    if (chrome == aBrowser)
++      return tmpPrivate;
++  }
++
++  return nsnull;
++}
++
++void
++EmbedPrivate::ContentStateChange(void)
++{
++
++  // we don't attach listeners to chrome
++  if (mListenersAttached && !mIsChrome)
++    return;
++
++  GetListener();
++
++  if (!mEventTarget)
++    return;
++
++  AttachListeners();
++
++}
++
++void
++EmbedPrivate::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
++EmbedPrivate::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
++EmbedPrivate::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
++EmbedPrivate::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
++EmbedPrivate::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;
++  }
++
++  // ok, all set.
++  mListenersAttached = PR_TRUE;
++}
++
++void
++EmbedPrivate::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;
++  }
++
++  mListenersAttached = PR_FALSE;
++}
++
++nsresult
++EmbedPrivate::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
++void *
++EmbedPrivate::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 */
++
++/* static */
++void
++EmbedPrivate::RegisterAppComponents(void)
++{
++  XRE_AddStaticComponent(&kDefaultPromptModule);
++}
++
++/* static */
++void
++EmbedPrivate::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
++EmbedPrivate::DestroyOffscreenWindow(void)
++{
++  if (!sOffscreenWindow)
++    return;
++  gtk_widget_destroy(sOffscreenWindow);
++  sOffscreenWindow = 0;
++}
+diff --git a/embedding/browser/gtk/src/EmbedPrivate.h b/embedding/browser/gtk/src/EmbedPrivate.h
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/src/EmbedPrivate.h
+@@ -0,0 +1,188 @@
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * Christopher Blizzard.
++ * Portions created by the Initial Developer are Copyright (C) 2001
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *   Christopher Blizzard <[email protected]>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#ifndef __EmbedPrivate_h
++#define __EmbedPrivate_h
++
++#include "nsCOMPtr.h"
++#include "nsStringGlue.h"
++#include "nsIWebNavigation.h"
++#include "nsISHistory.h"
++// for our one function that gets the EmbedPrivate via the chrome
++// object.
++#include "nsIWebBrowserChrome.h"
++#include "nsIAppShell.h"
++#include "nsPIDOMEventTarget.h"
++#include "nsTArray.h"
++
++#include "gtkmozembedprivate.h"
++
++class EmbedProgress;
++class EmbedWindow;
++class EmbedContentListener;
++class EmbedEventListener;
++
++class nsPIDOMWindow;
++class nsIDirectoryServiceProvider;
++
++class EmbedPrivate {
++
++ public:
++
++  EmbedPrivate();
++  ~EmbedPrivate();
++
++  nsresult    Init            (GtkMozEmbed *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 ();
++
++  static void PushStartup     (void);
++  static void PopStartup      (void);
++  static void SetPath         (const char *aPath);
++  static void SetCompPath     (const char *aPath);
++  static void SetProfilePath  (const char *aDir, const char *aName);
++  static void SetDirectoryServiceProvider (nsIDirectoryServiceProvider * appFileLocProvider);
++
++  nsresult OpenStream         (const char *aBaseURI, const char *aContentType);
++  nsresult AppendToStream     (const PRUint8 *aData, PRUint32 aLen);
++  nsresult CloseStream        (void);
++
++  // This function will find the specific EmbedPrivate object for a
++  // given nsIWebBrowserChrome.
++  static EmbedPrivate *FindPrivateForBrowser(nsIWebBrowserChrome *aBrowser);
++
++  // 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 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
++
++  GtkMozEmbed                   *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
++  nsCString                      mURI;
++
++  // the number of widgets that have been created
++  static PRUint32                sWidgetCount;
++  // the path to the GRE
++  static char                   *sPath;
++  // the path to components
++  static char                   *sCompPath;
++  // the appshell we have created
++  static nsIAppShell            *sAppShell;
++  // the list of all open windows
++  static nsTArray<EmbedPrivate*> *sWindowList;
++  // what is our profile path?
++  static nsILocalFile           *sProfileDir;
++  static nsISupports            *sProfileLock;
++
++  static nsIDirectoryServiceProvider * sAppFileLocProvider;
++
++  // 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);
++  
++  static void RegisterAppComponents();
++
++  // offscreen window methods and the offscreen widget
++  static void       EnsureOffscreenWindow(void);
++  static void       DestroyOffscreenWindow(void);
++  static GtkWidget *sOffscreenWindow;
++  static GtkWidget *sOffscreenFixed;
++ 
++};
++
++#endif /* __EmbedPrivate_h */
+diff --git a/embedding/browser/gtk/src/EmbedProgress.cpp b/embedding/browser/gtk/src/EmbedProgress.cpp
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/src/EmbedProgress.cpp
+@@ -0,0 +1,215 @@
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * Christopher Blizzard.
++ * Portions created by the Initial Developer are Copyright (C) 2001
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *   Christopher Blizzard <[email protected]>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#include "EmbedProgress.h"
++
++#include "nsIChannel.h"
++#include "nsIWebProgress.h"
++#include "nsIDOMWindow.h"
++
++#include "nsIURI.h"
++
++EmbedProgress::EmbedProgress(void)
++{
++  mOwner = nsnull;
++}
++
++EmbedProgress::~EmbedProgress()
++{
++}
++
++NS_IMPL_ISUPPORTS2(EmbedProgress,
++		   nsIWebProgressListener,
++		   nsISupportsWeakReference)
++
++nsresult
++EmbedProgress::Init(EmbedPrivate *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 & GTK_MOZ_EMBED_FLAG_IS_NETWORK) && 
++      (aStateFlags & GTK_MOZ_EMBED_FLAG_START))
++  {
++    g_signal_emit(G_OBJECT(mOwner->mOwningWidget),
++                  moz_embed_signals[NET_START], 0);
++  }
++
++  // get the uri for this request
++  nsCAutoString uriString;
++  RequestToURIString(aRequest, uriString);
++
++  // is it the same as the current URI?
++  if (mOwner->mURI.Equals(uriString))
++  {
++    // for people who know what they are doing
++    g_signal_emit(G_OBJECT(mOwner->mOwningWidget),
++                  moz_embed_signals[NET_STATE], 0,
++                  aStateFlags, aStatus);
++  }
++  g_signal_emit(G_OBJECT(mOwner->mOwningWidget),
++                moz_embed_signals[NET_STATE_ALL], 0,
++                uriString.get(),
++                (gint)aStateFlags, (gint)aStatus);
++  // and for stop, too
++  if ((aStateFlags & GTK_MOZ_EMBED_FLAG_IS_NETWORK) &&
++      (aStateFlags & GTK_MOZ_EMBED_FLAG_STOP))
++  {
++    g_signal_emit(G_OBJECT(mOwner->mOwningWidget),
++                  moz_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)
++{
++
++  nsCAutoString uriString;
++  RequestToURIString(aRequest, uriString);
++
++  // is it the same as the current uri?
++  if (mOwner->mURI.Equals(uriString)) {
++    g_signal_emit(G_OBJECT(mOwner->mOwningWidget),
++                  moz_embed_signals[PROGRESS], 0,
++                  aCurTotalProgress, aMaxTotalProgress);
++  }
++
++  g_signal_emit(G_OBJECT(mOwner->mOwningWidget),
++                moz_embed_signals[PROGRESS_ALL], 0,
++                uriString.get(),
++                aCurTotalProgress, aMaxTotalProgress);
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++EmbedProgress::OnLocationChange(nsIWebProgress *aWebProgress,
++				nsIRequest     *aRequest,
++				nsIURI         *aLocation)
++{
++  nsCAutoString 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(G_OBJECT(mOwner->mOwningWidget),
++                  moz_embed_signals[LOCATION], 0);
++  }
++
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++EmbedProgress::OnStatusChange(nsIWebProgress  *aWebProgress,
++			      nsIRequest      *aRequest,
++			      nsresult         aStatus,
++			      const PRUnichar *aMessage)
++{
++  g_signal_emit(G_OBJECT(mOwner->mOwningWidget),
++                moz_embed_signals[STATUS_CHANGE], 0,
++                static_cast<void *>(aRequest),
++                static_cast<int>(aStatus),
++                static_cast<const void *>(aMessage));
++
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++EmbedProgress::OnSecurityChange(nsIWebProgress *aWebProgress,
++				nsIRequest     *aRequest,
++				PRUint32         aState)
++{
++  g_signal_emit(G_OBJECT(mOwner->mOwningWidget),
++                moz_embed_signals[SECURITY_CHANGE], 0,
++                static_cast<void *>(aRequest),
++                aState);
++  return NS_OK;
++}
++
++/* static */
++void
++EmbedProgress::RequestToURIString(nsIRequest *aRequest, nsACString &aString)
++{
++  // is it a channel
++  nsCOMPtr<nsIChannel> channel;
++  channel = do_QueryInterface(aRequest);
++  if (!channel)
++    return;
++  
++  nsCOMPtr<nsIURI> uri;
++  channel->GetURI(getter_AddRefs(uri));
++  if (!uri)
++    return;
++  
++  uri->GetSpec(aString);
++}
+diff --git a/embedding/browser/gtk/src/EmbedProgress.h b/embedding/browser/gtk/src/EmbedProgress.h
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/src/EmbedProgress.h
+@@ -0,0 +1,66 @@
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * Christopher Blizzard.
++ * Portions created by the Initial Developer are Copyright (C) 2001
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *   Christopher Blizzard <[email protected]>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#ifndef __EmbedProgress_h
++#define __EmbedProgress_h
++
++#include "nsIWebProgressListener.h"
++#include "nsWeakReference.h"
++#include "EmbedPrivate.h"
++
++class EmbedProgress : public nsIWebProgressListener,
++                      public nsSupportsWeakReference
++{
++ public:
++  EmbedProgress();
++  virtual ~EmbedProgress();
++
++  nsresult Init(EmbedPrivate *aOwner);
++
++  NS_DECL_ISUPPORTS
++
++  NS_DECL_NSIWEBPROGRESSLISTENER
++
++ private:
++
++  static void RequestToURIString (nsIRequest *aRequest, nsACString &aString);
++
++  EmbedPrivate *mOwner;
++
++};
++
++#endif /* __EmbedProgress_h */
+diff --git a/embedding/browser/gtk/src/EmbedPrompter.cpp b/embedding/browser/gtk/src/EmbedPrompter.cpp
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/src/EmbedPrompter.cpp
+@@ -0,0 +1,411 @@
++/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
++/* vim:expandtab:shiftwidth=4:tabstop=4: */
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * Netscape Communications Corporation.
++ * Portions created by the Initial Developer are Copyright (C) 2003
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *  Brian Ryner <[email protected]>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#include "EmbedPrompter.h"
++
++enum {
++    INCLUDE_USERNAME = 1 << 0,
++    INCLUDE_PASSWORD = 1 << 1,
++    INCLUDE_CHECKBOX = 1 << 2,
++    INCLUDE_CANCEL   = 1 << 3
++};
++
++struct DialogDescription {
++    int          flags;
++    const gchar* icon;
++};
++
++// This table contains the optional widgets and icons associated with
++// each type of dialog.
++
++static const DialogDescription DialogTable[] = {
++    { 0,                      GTK_STOCK_DIALOG_WARNING  },  // ALERT
++    { INCLUDE_CHECKBOX,       GTK_STOCK_DIALOG_WARNING  },  // ALERT_CHECK
++    { INCLUDE_CANCEL,         GTK_STOCK_DIALOG_QUESTION },  // CONFIRM
++    { INCLUDE_CHECKBOX |
++      INCLUDE_CANCEL,         GTK_STOCK_DIALOG_QUESTION },  // CONFIRM_CHECK
++    { INCLUDE_CANCEL |
++      INCLUDE_CHECKBOX,       GTK_STOCK_DIALOG_QUESTION },  // PROMPT
++    { INCLUDE_CANCEL |
++      INCLUDE_USERNAME |
++      INCLUDE_PASSWORD |
++      INCLUDE_CHECKBOX,       GTK_STOCK_DIALOG_QUESTION },  // PROMPT_USER_PASS
++    { INCLUDE_CANCEL |
++      INCLUDE_PASSWORD |
++      INCLUDE_CHECKBOX,       GTK_STOCK_DIALOG_QUESTION },  // PROMPT_PASS
++    { INCLUDE_CANCEL,         GTK_STOCK_DIALOG_QUESTION },  // SELECT
++    { INCLUDE_CANCEL |
++      INCLUDE_CHECKBOX,       GTK_STOCK_DIALOG_QUESTION }   // UNIVERSAL
++};
++
++EmbedPrompter::EmbedPrompter(void)
++    : mCheckValue(PR_FALSE),
++      mItemList(nsnull),
++      mItemCount(0),
++      mButtonPressed(0),
++      mConfirmResult(PR_FALSE),
++      mSelectedItem(0),
++      mWindow(NULL),
++      mUserField(NULL),
++      mPassField(NULL),
++      mTextField(NULL),
++      mComboBox(NULL),
++      mCheckBox(NULL)
++{
++}
++
++EmbedPrompter::~EmbedPrompter(void)
++{
++    if (mItemList)
++        delete[] mItemList;
++}
++
++nsresult
++EmbedPrompter::Create(PromptType aType, GtkWindow* aParentWindow)
++{
++    mWindow = gtk_dialog_new_with_buttons(mTitle.get(), aParentWindow,
++                                          (GtkDialogFlags)0,
++                                          NULL);
++
++    // only add the dialog to the window group if the parent already has a window group,
++    // so as not to break app's expectations about modal dialogs.
++    if (aParentWindow && aParentWindow->group) {
++        gtk_window_group_add_window (aParentWindow->group, GTK_WINDOW (mWindow));
++    }
++
++    // gtk will resize this for us as necessary
++    gtk_window_set_default_size(GTK_WINDOW(mWindow), 100, 50);
++
++    // this HBox will contain the icon, and a vbox which contains the
++    // dialog text and other widgets.
++    GtkWidget* dialogHBox = gtk_hbox_new(FALSE, 12);
++
++
++    // Set up dialog properties according to the GNOME HIG
++    // (http://developer.gnome.org/projects/gup/hig/1.0/windows.html#alert-windows)
++
++    gtk_container_set_border_width(GTK_CONTAINER(mWindow), 6);
++    gtk_dialog_set_has_separator(GTK_DIALOG(mWindow), FALSE);
++    gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(mWindow)->vbox), 12);
++    gtk_container_set_border_width(GTK_CONTAINER(dialogHBox), 6);
++
++
++    // This is the VBox which will contain the label and other controls.
++    GtkWidget* contentsVBox = gtk_vbox_new(FALSE, 12);
++
++    // get the stock icon for this dialog and put it in the box
++    const gchar* iconDesc = DialogTable[aType].icon;
++    GtkWidget* icon = gtk_image_new_from_stock(iconDesc, GTK_ICON_SIZE_DIALOG);
++    gtk_misc_set_alignment(GTK_MISC(icon), 0.5, 0.0);
++    gtk_box_pack_start(GTK_BOX(dialogHBox), icon, FALSE, FALSE, 0);
++
++    // now pack the label into the vbox
++    GtkWidget* label = gtk_label_new(mMessageText.get());
++    gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
++    gtk_label_set_selectable(GTK_LABEL(label), TRUE);
++    gtk_box_pack_start(GTK_BOX(contentsVBox), label, FALSE, FALSE, 0);
++
++    int widgetFlags = DialogTable[aType].flags;
++
++    if (widgetFlags & (INCLUDE_USERNAME | INCLUDE_PASSWORD)) {
++
++        // If we're creating a username and/or password field, make an hbox
++        // which will contain two vboxes, one for the labels and one for the
++        // text fields.  This will let us line up the textfields.
++
++        GtkWidget* userPassHBox = gtk_hbox_new(FALSE, 12);
++        GtkWidget* userPassLabels = gtk_vbox_new(TRUE, 6);
++        GtkWidget* userPassFields = gtk_vbox_new(TRUE, 6);
++
++        if (widgetFlags & INCLUDE_USERNAME) {
++            GtkWidget* userLabel = gtk_label_new("User Name:");
++            gtk_box_pack_start(GTK_BOX(userPassLabels), userLabel, FALSE,
++                               FALSE, 0);
++
++            mUserField = gtk_entry_new();
++
++            if (!mUser.IsEmpty())
++                gtk_entry_set_text(GTK_ENTRY(mUserField), mUser.get());
++
++            gtk_entry_set_activates_default(GTK_ENTRY(mUserField), TRUE);
++
++            gtk_box_pack_start(GTK_BOX(userPassFields), mUserField, FALSE,
++                               FALSE, 0);
++        }
++        if (widgetFlags & INCLUDE_PASSWORD) {
++            GtkWidget* passLabel = gtk_label_new("Password:");
++            gtk_box_pack_start(GTK_BOX(userPassLabels), passLabel, FALSE,
++                               FALSE, 0);
++
++            mPassField = gtk_entry_new();
++
++            if (!mPass.IsEmpty())
++                gtk_entry_set_text(GTK_ENTRY(mPassField), mPass.get());
++
++            gtk_entry_set_visibility(GTK_ENTRY(mPassField), FALSE);
++            gtk_entry_set_activates_default(GTK_ENTRY(mPassField), TRUE);
++
++            gtk_box_pack_start(GTK_BOX(userPassFields), mPassField, FALSE,
++                               FALSE, 0);
++        }
++
++        gtk_box_pack_start(GTK_BOX(userPassHBox), userPassLabels, FALSE,
++                           FALSE, 0);
++        gtk_box_pack_start(GTK_BOX(userPassHBox), userPassFields, FALSE,
++                           FALSE, 0);
++        gtk_box_pack_start(GTK_BOX(contentsVBox), userPassHBox, FALSE, FALSE, 0);
++    }
++
++    if (aType == TYPE_PROMPT) {
++        mTextField = gtk_entry_new();
++
++        if (!mTextValue.IsEmpty())
++            gtk_entry_set_text(GTK_ENTRY(mTextField), mTextValue.get());
++
++        gtk_entry_set_activates_default(GTK_ENTRY(mTextField), TRUE);
++
++        gtk_box_pack_start(GTK_BOX(contentsVBox), mTextField, FALSE, FALSE, 0);
++    }
++
++    // Add a checkbox
++    if ((widgetFlags & INCLUDE_CHECKBOX) && !mCheckMessage.IsEmpty()) {
++        mCheckBox = gtk_check_button_new_with_label(mCheckMessage.get());
++
++        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mCheckBox),
++                                     mCheckValue);
++        gtk_label_set_line_wrap(GTK_LABEL(gtk_bin_get_child(GTK_BIN(mCheckBox))),
++				TRUE);
++
++        gtk_box_pack_start(GTK_BOX(contentsVBox), mCheckBox, FALSE, FALSE, 0);
++    }
++
++    // Add a dropdown menu
++    if (aType == TYPE_SELECT) {
++        // Build up a GtkComboBox containing the items
++        GtkWidget* mComboBox = gtk_combo_box_new_text();
++        for (PRUint32 i = 0; i < mItemCount; ++i) {
++            gtk_combo_box_append_text(GTK_COMBO_BOX(mComboBox), mItemList[i].get());
++        }
++        gtk_box_pack_start(GTK_BOX(contentsVBox), mComboBox, FALSE, FALSE, 0);
++    }
++
++    if (aType == TYPE_UNIVERSAL) {
++        // Create buttons based on the flags passed in.
++        for (PRUint32 i = EMBED_MAX_BUTTONS; i-- > 0; ) {
++            if (!mButtonLabels[i].IsEmpty())
++                gtk_dialog_add_button(GTK_DIALOG(mWindow),
++                                      mButtonLabels[i].get(), i);
++        }
++        gtk_dialog_set_default_response(GTK_DIALOG(mWindow), 0);
++    } else {
++        // Create standard ok and cancel buttons
++        if (widgetFlags & INCLUDE_CANCEL)
++            gtk_dialog_add_button(GTK_DIALOG(mWindow), GTK_STOCK_CANCEL,
++                                  GTK_RESPONSE_CANCEL);
++
++        GtkWidget* okButton = gtk_dialog_add_button(GTK_DIALOG(mWindow),
++                                                    GTK_STOCK_OK,
++                                                    GTK_RESPONSE_ACCEPT);
++        gtk_widget_grab_default(okButton);
++    }
++
++    // Pack the contentsVBox into the dialogHBox and the dialog.
++    gtk_box_pack_start(GTK_BOX(dialogHBox), contentsVBox, FALSE, FALSE, 0);
++    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(mWindow)->vbox), dialogHBox, FALSE,
++                       FALSE, 0);
++
++    return NS_OK;
++}
++
++void
++EmbedPrompter::SetTitle(const PRUnichar *aTitle)
++{
++    mTitle.Assign(NS_ConvertUTF16toUTF8(aTitle));
++}
++
++void
++EmbedPrompter::SetTextValue(const PRUnichar *aTextValue)
++{
++    mTextValue.Assign(NS_ConvertUTF16toUTF8(aTextValue));
++}
++
++void
++EmbedPrompter::SetCheckMessage(const PRUnichar *aMessage)
++{
++    mCheckMessage.Assign(NS_ConvertUTF16toUTF8(aMessage));
++}
++
++void
++EmbedPrompter::SetMessageText(const PRUnichar *aMessageText)
++{
++    mMessageText.Assign(NS_ConvertUTF16toUTF8(aMessageText));
++}
++
++void
++EmbedPrompter::SetUser(const PRUnichar *aUser)
++{
++    mUser.Assign(NS_ConvertUTF16toUTF8(aUser));
++}
++
++void
++EmbedPrompter::SetPassword(const PRUnichar *aPass)
++{
++    mPass.Assign(NS_ConvertUTF16toUTF8(aPass));
++}
++
++void
++EmbedPrompter::SetCheckValue(const PRBool aValue)
++{
++    mCheckValue = aValue;
++}
++
++void
++EmbedPrompter::SetItems(const PRUnichar** aItemArray, PRUint32 aCount)
++{
++    if (mItemList)
++        delete[] mItemList;
++
++    mItemCount = aCount;
++    mItemList = new nsCString[aCount];
++    for (PRUint32 i = 0; i < aCount; ++i)
++        mItemList[i].Assign(NS_ConvertUTF16toUTF8(aItemArray[i]));
++}
++
++void
++EmbedPrompter::SetButtons(const PRUnichar* aButton0Label,
++                          const PRUnichar* aButton1Label,
++                          const PRUnichar* aButton2Label)
++{
++    mButtonLabels[0].Assign(NS_ConvertUTF16toUTF8(aButton0Label));
++    mButtonLabels[1].Assign(NS_ConvertUTF16toUTF8(aButton1Label));
++    mButtonLabels[2].Assign(NS_ConvertUTF16toUTF8(aButton2Label));
++}
++
++void
++EmbedPrompter::GetCheckValue(PRBool *aValue)
++{
++    *aValue = mCheckValue;
++}
++
++void
++EmbedPrompter::GetConfirmValue(PRBool *aConfirmValue)
++{
++    *aConfirmValue = mConfirmResult;
++}
++ 
++void
++EmbedPrompter::GetTextValue(PRUnichar **aTextValue)
++{
++    *aTextValue = ToNewUnicode(NS_ConvertUTF8toUTF16(mTextValue));
++}
++
++void
++EmbedPrompter::GetUser(PRUnichar **aUser)
++{
++    *aUser = ToNewUnicode(NS_ConvertUTF8toUTF16(mUser));
++}
++
++void
++EmbedPrompter::GetPassword(PRUnichar **aPass)
++{
++    *aPass = ToNewUnicode(NS_ConvertUTF8toUTF16(mPass));
++}
++
++void
++EmbedPrompter::GetSelectedItem(PRInt32 *aIndex)
++{
++    *aIndex = mSelectedItem;
++}
++
++void
++EmbedPrompter::GetButtonPressed(PRInt32 *aButton)
++{
++    *aButton = mButtonPressed;
++}
++
++void
++EmbedPrompter::Run(void)
++{
++    gtk_widget_show_all(mWindow);
++    gint response = gtk_dialog_run(GTK_DIALOG(mWindow));
++    switch (response) {
++    case GTK_RESPONSE_NONE:
++    case GTK_RESPONSE_CANCEL:
++    case GTK_RESPONSE_DELETE_EVENT:
++        mConfirmResult = PR_FALSE;
++        break;
++    case GTK_RESPONSE_ACCEPT:
++        mConfirmResult = PR_TRUE;
++        SaveDialogValues();
++        break;
++    default:
++        mButtonPressed = response;
++        SaveDialogValues();
++    }
++
++    gtk_widget_destroy(mWindow);
++}
++
++void
++EmbedPrompter::SaveDialogValues()
++{
++    if (mUserField)
++        mUser.Assign(gtk_entry_get_text(GTK_ENTRY(mUserField)));
++
++    if (mPassField)
++        mPass.Assign(gtk_entry_get_text(GTK_ENTRY(mPassField)));
++
++    if (mCheckBox)
++        mCheckValue = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mCheckBox));
++
++    if (mTextField)
++        mTextValue.Assign(gtk_entry_get_text(GTK_ENTRY(mTextField)));
++
++    if (mComboBox)
++    {
++        gchar *str = gtk_combo_box_get_active_text(GTK_COMBO_BOX(mComboBox));
++        for (PRUint32 i = 0; i < mItemCount; ++i) {
++            if(mItemList[i].Equals(str))
++            {
++                mSelectedItem = i;
++                break;
++            }
++        }
++    }
++}
+diff --git a/embedding/browser/gtk/src/EmbedPrompter.h b/embedding/browser/gtk/src/EmbedPrompter.h
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/src/EmbedPrompter.h
+@@ -0,0 +1,113 @@
++/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
++/* vim:expandtab:shiftwidth=4:tabstop=4: */
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * Christopher Blizzard.
++ * Portions created by the Initial Developer are Copyright (C) 2001
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *   Christopher Blizzard <[email protected]>
++ *   Brian Ryner <[email protected]>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#include "nsStringGlue.h"
++#include <gtk/gtk.h>
++
++#define EMBED_MAX_BUTTONS 3
++
++class EmbedPrompter {
++
++public:
++
++    EmbedPrompter();
++    ~EmbedPrompter();
++
++    enum PromptType {
++        TYPE_ALERT,
++        TYPE_ALERT_CHECK,
++        TYPE_CONFIRM,
++        TYPE_CONFIRM_CHECK,
++        TYPE_PROMPT,
++        TYPE_PROMPT_USER_PASS,
++        TYPE_PROMPT_PASS,
++        TYPE_SELECT,
++        TYPE_UNIVERSAL
++    };
++
++    nsresult Create(PromptType aType, GtkWindow* aParentWindow);
++    void     SetTitle(const PRUnichar *aTitle);
++    void     SetTextValue (const PRUnichar *aTextValue);
++    void     SetCheckMessage(const PRUnichar *aCheckMessage);
++    void     SetCheckValue(const PRBool aValue);
++    void     SetMessageText(const PRUnichar *aMessageText);
++    void     SetUser(const PRUnichar *aUser);
++    void     SetPassword(const PRUnichar *aPass);
++    void     SetButtons(const PRUnichar* aButton0Label,
++                        const PRUnichar* aButton1Label,
++                        const PRUnichar* aButton2Label);
++    void     SetItems(const PRUnichar **aItemArray, PRUint32 aCount);
++
++    void     GetCheckValue(PRBool *aValue);
++    void     GetConfirmValue(PRBool *aConfirmValue);
++    void     GetTextValue(PRUnichar **aTextValue);
++    void     GetUser(PRUnichar **aUser);
++    void     GetPassword(PRUnichar **aPass);
++    void     GetButtonPressed(PRInt32 *aButton);
++    void     GetSelectedItem(PRInt32 *aIndex);
++
++    void     Run(void);
++
++private:
++
++    void     SaveDialogValues();
++
++    nsCString    mTitle;
++    nsCString    mMessageText;
++    nsCString    mTextValue;
++    nsCString    mCheckMessage;
++    PRBool       mCheckValue;
++    nsCString    mUser;
++    nsCString    mPass;
++    nsCString    mButtonLabels[EMBED_MAX_BUTTONS];
++    nsCString   *mItemList;
++    PRUint32     mItemCount;
++
++    PRInt32      mButtonPressed;
++    PRBool       mConfirmResult;
++    PRInt32      mSelectedItem;
++
++    GtkWidget   *mWindow;
++    GtkWidget   *mUserField;
++    GtkWidget   *mPassField;
++    GtkWidget   *mTextField;
++    GtkWidget   *mComboBox;
++    GtkWidget   *mCheckBox;
++};
+diff --git a/embedding/browser/gtk/src/EmbedWindow.cpp b/embedding/browser/gtk/src/EmbedWindow.cpp
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/src/EmbedWindow.cpp
+@@ -0,0 +1,474 @@
++/*
++ * vim:ts=2:et:sw=2
++ *
++ * ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * Christopher Blizzard.
++ * Portions created by the Initial Developer are Copyright (C) 2001
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *   Christopher Blizzard <[email protected]>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#include "nsCWebBrowser.h"
++#include "nsIComponentManager.h"
++#include "nsComponentManagerUtils.h"
++#include "nsIDocShellTreeItem.h"
++#include "nsIWidget.h"
++
++#include "EmbedWindow.h"
++#include "EmbedPrivate.h"
++#include "EmbedPrompter.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(EmbedPrivate *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(G_OBJECT(mOwner->mOwningWidget),
++                    moz_embed_signals[JS_STATUS], 0);
++    }
++    break;
++  case STATUS_SCRIPT_DEFAULT:
++    // Gee, that's nice.
++    break;
++  case STATUS_LINK:
++    {
++      mLinkMessage = aStatus;
++      g_signal_emit(G_OBJECT(mOwner->mOwningWidget),
++                    moz_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(G_OBJECT(mOwner->mOwningWidget),
++                moz_embed_signals[DESTROY_BROWSER], 0);
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++EmbedWindow::SizeBrowserTo(PRInt32 aCX, PRInt32 aCY)
++{
++  g_signal_emit(G_OBJECT(mOwner->mOwningWidget),
++                moz_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(G_OBJECT(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(G_OBJECT(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 = ToNewUnicode(mTitle);
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++EmbedWindow::SetTitle(const PRUnichar *aTitle)
++{
++  mTitle = aTitle;
++  g_signal_emit(G_OBJECT(mOwner->mOwningWidget),
++                moz_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)
++{
++  // XXX See bug 312998
++  // 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(G_OBJECT(mOwner->mOwningWidget),
++                moz_embed_signals[VISIBILITY], 0,
++                aVisibility);
++  return NS_OK;
++}
++
++// nsITooltipListener
++
++static gint
++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)
++{
++  nsAutoString tipText ( aTipText );
++
++  const char* tipString = ToNewUTF8String(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_resizable(GTK_WINDOW(sTipWindow), TRUE);
++  // needed to get colors + fonts etc correctly
++  gtk_widget_set_name(sTipWindow, "gtk-tooltips");
++  gtk_window_set_type_hint(GTK_WINDOW(sTipWindow), GDK_WINDOW_TYPE_HINT_TOOLTIP);
++  
++  // 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!");
++    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(tipString);
++  // 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);
++
++  NS_Free( (void*)tipString );
++
++  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/embedding/browser/gtk/src/EmbedWindow.h b/embedding/browser/gtk/src/EmbedWindow.h
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/src/EmbedWindow.h
+@@ -0,0 +1,101 @@
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * Christopher Blizzard.
++ * Portions created by the Initial Developer are Copyright (C) 2001
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *   Christopher Blizzard <[email protected]>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#ifndef __EmbedWindow_h
++#define __EmbedWindow_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 "nsStringGlue.h"
++
++#include <gtk/gtk.h>
++
++class EmbedPrivate;
++
++class EmbedWindow : public nsIWebBrowserChrome,
++		    public nsIWebBrowserChromeFocus,
++                    public nsIEmbeddingSiteWindow,
++                    public nsITooltipListener,
++		    public nsIInterfaceRequestor
++{
++
++ public:
++
++  EmbedWindow();
++  virtual ~EmbedWindow();
++
++  nsresult Init            (EmbedPrivate *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
++
++  nsString                 mTitle;
++  nsString                 mJSStatus;
++  nsString                 mLinkMessage;
++
++  nsCOMPtr<nsIBaseWindow>  mBaseWindow; // [OWNER]
++
++private:
++
++  EmbedPrivate            *mOwner;
++  nsCOMPtr<nsIWebBrowser>  mWebBrowser; // [OWNER]
++  static GtkWidget        *sTipWindow;
++  PRBool                   mVisibility;
++  PRBool                   mIsModal;
++
++};
++  
++
++#endif /* __EmbedWindow_h */
+diff --git a/embedding/browser/gtk/src/EmbedWindowCreator.cpp b/embedding/browser/gtk/src/EmbedWindowCreator.cpp
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/src/EmbedWindowCreator.cpp
+@@ -0,0 +1,106 @@
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright (C) Christopher Blizzard.  All Rights Reserved.
++ * Portions created by the Initial Developer are Copyright (C) 2001
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *   Christopher Blizzard <[email protected]>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#include "EmbedWindowCreator.h"
++#include "EmbedPrivate.h"
++#include "EmbedWindow.h"
++
++// in order to create orphaned windows
++#include "gtkmozembedprivate.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);
++
++  GtkMozEmbed *newEmbed = nsnull;
++
++  // No parent?  Ask via the singleton object instead.
++  if (!aParent) {
++    gtk_moz_embed_single_create_window(&newEmbed,
++				       (guint)aChromeFlags);
++  }
++  else {
++    // Find the EmbedPrivate object for this web browser chrome object.
++    EmbedPrivate *embedPrivate = EmbedPrivate::FindPrivateForBrowser(aParent);
++    
++    if (!embedPrivate)
++      return NS_ERROR_FAILURE;
++    
++    g_signal_emit(G_OBJECT(embedPrivate->mOwningWidget),
++                  moz_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));
++  
++  EmbedPrivate *newEmbedPrivate = static_cast<EmbedPrivate *>(newEmbed->data);
++
++  // set the chrome flag on the new window if it's a chrome open
++  if (aChromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME)
++    newEmbedPrivate->mIsChrome = PR_TRUE;
++
++  *_retval = static_cast<nsIWebBrowserChrome *>(newEmbedPrivate->mWindow);
++  
++  if (*_retval) {
++    NS_ADDREF(*_retval);
++    return NS_OK;
++  }
++
++  return NS_ERROR_FAILURE;
++}
+diff --git a/embedding/browser/gtk/src/EmbedWindowCreator.h b/embedding/browser/gtk/src/EmbedWindowCreator.h
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/src/EmbedWindowCreator.h
+@@ -0,0 +1,54 @@
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * Christopher Blizzard.
++ * Portions created by the Initial Developer are Copyright (C) 2001
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *   Christopher Blizzard <[email protected]>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#ifndef __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/embedding/browser/gtk/src/GtkPromptService.cpp b/embedding/browser/gtk/src/GtkPromptService.cpp
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/src/GtkPromptService.cpp
+@@ -0,0 +1,349 @@
++/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
++/* vim:expandtab:shiftwidth=4:tabstop=4: */
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * Netscape Communications Corporation.
++ * Portions created by the Initial Developer are Copyright (C) 2003
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *  Brian Ryner <[email protected]>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#include "GtkPromptService.h"
++#include "EmbedPrompter.h"
++#include "nsStringGlue.h"
++#include "nsIWindowWatcher.h"
++#include "nsIWebBrowserChrome.h"
++#include "nsIEmbeddingSiteWindow.h"
++#include "nsCOMPtr.h"
++#include "nsIServiceManager.h"
++#include "nsServiceManagerUtils.h"
++
++GtkPromptService::GtkPromptService()
++{
++}
++
++GtkPromptService::~GtkPromptService()
++{
++}
++
++NS_IMPL_ISUPPORTS1(GtkPromptService, nsIPromptService)
++
++NS_IMETHODIMP
++GtkPromptService::Alert(nsIDOMWindow* aParent, const PRUnichar* aDialogTitle, 
++                        const PRUnichar* aDialogText)
++{
++    EmbedPrompter prompter;
++    prompter.SetTitle(aDialogTitle ? aDialogTitle : NS_LITERAL_STRING("Alert").get());
++    prompter.SetMessageText(aDialogText);
++    prompter.Create(EmbedPrompter::TYPE_ALERT, 
++                    GetGtkWindowForDOMWindow(aParent));
++    prompter.Run();
++    return NS_OK;
++}
++
++NS_IMETHODIMP
++GtkPromptService::AlertCheck(nsIDOMWindow* aParent,
++                             const PRUnichar* aDialogTitle,
++                             const PRUnichar* aDialogText,
++                             const PRUnichar* aCheckMsg, PRBool* aCheckValue)
++{
++    NS_ENSURE_ARG_POINTER(aCheckValue);
++
++    EmbedPrompter prompter;
++    prompter.SetTitle(aDialogTitle ? aDialogTitle : NS_LITERAL_STRING("Alert").get());
++    prompter.SetMessageText(aDialogText);
++    prompter.SetCheckMessage(aCheckMsg);
++    prompter.SetCheckValue(*aCheckValue);
++    prompter.Create(EmbedPrompter::TYPE_ALERT_CHECK,
++                    GetGtkWindowForDOMWindow(aParent));
++    prompter.Run();
++    prompter.GetCheckValue(aCheckValue);
++    return NS_OK;
++}
++
++NS_IMETHODIMP
++GtkPromptService::Confirm(nsIDOMWindow* aParent,
++                          const PRUnichar* aDialogTitle,
++                          const PRUnichar* aDialogText, PRBool* aConfirm)
++{
++    EmbedPrompter prompter;
++    prompter.SetTitle(aDialogTitle ? aDialogTitle : NS_LITERAL_STRING("Confirm").get());
++    prompter.SetMessageText(aDialogText);
++    prompter.Create(EmbedPrompter::TYPE_CONFIRM,
++                    GetGtkWindowForDOMWindow(aParent));
++    prompter.Run();
++    prompter.GetConfirmValue(aConfirm);
++    return NS_OK;
++}
++
++NS_IMETHODIMP
++GtkPromptService::ConfirmCheck(nsIDOMWindow* aParent,
++                               const PRUnichar* aDialogTitle,
++                               const PRUnichar* aDialogText,
++                               const PRUnichar* aCheckMsg,
++                               PRBool* aCheckValue, PRBool* aConfirm)
++{
++    NS_ENSURE_ARG_POINTER(aCheckValue);
++
++    EmbedPrompter prompter;
++    prompter.SetTitle(aDialogTitle ? aDialogTitle : NS_LITERAL_STRING("Confirm").get());
++    prompter.SetMessageText(aDialogText);
++    prompter.SetCheckMessage(aCheckMsg);
++    prompter.SetCheckValue(*aCheckValue);
++    prompter.Create(EmbedPrompter::TYPE_CONFIRM_CHECK,
++                    GetGtkWindowForDOMWindow(aParent));
++    prompter.Run();
++    prompter.GetCheckValue(aCheckValue);
++    prompter.GetConfirmValue(aConfirm);
++    return NS_OK;
++}
++
++NS_IMETHODIMP
++GtkPromptService::ConfirmEx(nsIDOMWindow* aParent,
++                            const PRUnichar* aDialogTitle,
++                            const PRUnichar* aDialogText,
++                            PRUint32 aButtonFlags,
++                            const PRUnichar* aButton0Title,
++                            const PRUnichar* aButton1Title,
++                            const PRUnichar* aButton2Title,
++                            const PRUnichar* aCheckMsg, PRBool* aCheckValue,
++                            PRInt32* aRetVal)
++{
++    EmbedPrompter prompter;
++    prompter.SetTitle(aDialogTitle ? aDialogTitle : NS_LITERAL_STRING("Confirm").get());
++    prompter.SetMessageText(aDialogText);
++
++    nsAutoString button0Label, button1Label, button2Label;
++    GetButtonLabel(aButtonFlags, BUTTON_POS_0, aButton0Title, button0Label);
++    GetButtonLabel(aButtonFlags, BUTTON_POS_1, aButton1Title, button1Label);
++    GetButtonLabel(aButtonFlags, BUTTON_POS_2, aButton2Title, button2Label);
++    prompter.SetButtons(button0Label.get(), button1Label.get(),
++                        button2Label.get());
++
++    if (aCheckMsg)
++        prompter.SetCheckMessage(aCheckMsg);
++    if (aCheckValue)
++        prompter.SetCheckValue(*aCheckValue);
++
++    prompter.Create(EmbedPrompter::TYPE_UNIVERSAL,
++                    GetGtkWindowForDOMWindow(aParent));
++    prompter.Run();
++
++    if (aCheckValue)
++        prompter.GetCheckValue(aCheckValue);
++
++    prompter.GetButtonPressed(aRetVal);
++
++    return NS_OK;
++}
++
++NS_IMETHODIMP
++GtkPromptService::Prompt(nsIDOMWindow* aParent, const PRUnichar* aDialogTitle,
++                         const PRUnichar* aDialogText, PRUnichar** aValue,
++                         const PRUnichar* aCheckMsg, PRBool* aCheckValue,
++                         PRBool* aConfirm)
++{
++    EmbedPrompter prompter;
++    prompter.SetTitle(aDialogTitle ? aDialogTitle : NS_LITERAL_STRING("Prompt").get());
++    prompter.SetMessageText(aDialogText);
++    prompter.SetTextValue(*aValue);
++    if (aCheckMsg)
++        prompter.SetCheckMessage(aCheckMsg);
++    if (aCheckValue)
++        prompter.SetCheckValue(*aCheckValue);
++
++    prompter.Create(EmbedPrompter::TYPE_PROMPT,
++                    GetGtkWindowForDOMWindow(aParent));
++    prompter.Run();
++    if (aCheckValue)
++        prompter.GetCheckValue(aCheckValue);
++    prompter.GetConfirmValue(aConfirm);
++    if (*aConfirm) {
++        if (*aValue)
++            NS_Free(*aValue);
++        prompter.GetTextValue(aValue);
++    }
++    return NS_OK;
++}
++
++NS_IMETHODIMP
++GtkPromptService::PromptUsernameAndPassword(nsIDOMWindow* aParent,
++                                            const PRUnichar* aDialogTitle,
++                                            const PRUnichar* aDialogText,
++                                            PRUnichar** aUsername,
++                                            PRUnichar** aPassword,
++                                            const PRUnichar* aCheckMsg,
++                                            PRBool* aCheckValue,
++                                            PRBool* aConfirm)
++{
++    EmbedPrompter prompter;
++    prompter.SetTitle(aDialogTitle ? aDialogTitle : NS_LITERAL_STRING("Prompt").get());
++    prompter.SetMessageText(aDialogText);
++    prompter.SetUser(*aUsername);
++    prompter.SetPassword(*aPassword);
++    if (aCheckMsg)
++        prompter.SetCheckMessage(aCheckMsg);
++    if (aCheckValue)
++        prompter.SetCheckValue(*aCheckValue);
++
++    prompter.Create(EmbedPrompter::TYPE_PROMPT_USER_PASS,
++                    GetGtkWindowForDOMWindow(aParent));
++    prompter.Run();
++    if (aCheckValue)
++        prompter.GetCheckValue(aCheckValue);
++    prompter.GetConfirmValue(aConfirm);
++    if (*aConfirm) {
++        if (*aUsername)
++            NS_Free(*aUsername);
++        prompter.GetUser(aUsername);
++
++        if (*aPassword)
++            NS_Free(*aPassword);
++        prompter.GetPassword(aPassword);
++    }
++    return NS_OK;
++}
++
++NS_IMETHODIMP
++GtkPromptService::PromptPassword(nsIDOMWindow* aParent,
++                                 const PRUnichar* aDialogTitle,
++                                 const PRUnichar* aDialogText,
++                                 PRUnichar** aPassword,
++                                 const PRUnichar* aCheckMsg,
++                                 PRBool* aCheckValue, PRBool* aConfirm)
++{
++    EmbedPrompter prompter;
++    prompter.SetTitle(aDialogTitle ? aDialogTitle : NS_LITERAL_STRING("Prompt").get());
++    prompter.SetMessageText(aDialogText);
++    prompter.SetPassword(*aPassword);
++    if (aCheckMsg)
++        prompter.SetCheckMessage(aCheckMsg);
++    if (aCheckValue)
++        prompter.SetCheckValue(*aCheckValue);
++
++    prompter.Create(EmbedPrompter::TYPE_PROMPT_PASS,
++                    GetGtkWindowForDOMWindow(aParent));
++    prompter.Run();
++    if (aCheckValue)
++        prompter.GetCheckValue(aCheckValue);
++    prompter.GetConfirmValue(aConfirm);
++    if (*aConfirm) {
++        if (*aPassword)
++            NS_Free(*aPassword);
++        prompter.GetPassword(aPassword);
++    }
++    return NS_OK;
++}
++
++NS_IMETHODIMP
++GtkPromptService::Select(nsIDOMWindow* aParent, const PRUnichar* aDialogTitle,
++                         const PRUnichar* aDialogText, PRUint32 aCount,
++                         const PRUnichar** aSelectList, PRInt32* outSelection,
++                         PRBool* aConfirm)
++{
++    EmbedPrompter prompter;
++    prompter.SetTitle(aDialogTitle ? aDialogTitle : NS_LITERAL_STRING("Select").get());
++    prompter.SetMessageText(aDialogText);
++    prompter.SetItems(aSelectList, aCount);
++    prompter.Create(EmbedPrompter::TYPE_SELECT,
++                    GetGtkWindowForDOMWindow(aParent));
++    prompter.Run();
++    prompter.GetSelectedItem(outSelection);
++    prompter.GetConfirmValue(aConfirm);
++    return NS_OK;
++}
++
++GtkWindow*
++GtkPromptService::GetGtkWindowForDOMWindow(nsIDOMWindow* aDOMWindow)
++{
++    nsCOMPtr<nsIWindowWatcher> wwatch = do_GetService("@mozilla.org/embedcomp/window-watcher;1");
++
++    if (!aDOMWindow)
++        return NULL;
++
++    nsCOMPtr<nsIWebBrowserChrome> chrome;
++    wwatch->GetChromeForWindow(aDOMWindow, getter_AddRefs(chrome));
++    nsCOMPtr<nsIEmbeddingSiteWindow> siteWindow = do_QueryInterface(chrome);
++
++    if (!siteWindow)
++        return NULL;
++
++    GtkWidget* parentWidget;
++    siteWindow->GetSiteWindow((void**)&parentWidget);
++
++    if (!parentWidget)
++        return NULL;
++
++    GtkWidget* gtkWin = gtk_widget_get_toplevel(parentWidget);
++    if (GTK_WIDGET_TOPLEVEL(gtkWin))
++        return GTK_WINDOW(gtkWin);
++
++    return NULL;
++}
++
++void
++GtkPromptService::GetButtonLabel(PRUint32 aFlags, PRUint32 aPos,
++                                 const PRUnichar* aStringValue,
++                                 nsAString& aLabel)
++{
++    PRUint32 posFlag = (aFlags & (255 * aPos)) / aPos;
++    switch (posFlag) {
++    case 0:
++        break;
++    case BUTTON_TITLE_OK:
++        aLabel.AssignLiteral(GTK_STOCK_OK);
++        break;
++    case BUTTON_TITLE_CANCEL:
++        aLabel.AssignLiteral(GTK_STOCK_CANCEL);
++        break;
++    case BUTTON_TITLE_YES:
++        aLabel.AssignLiteral(GTK_STOCK_YES);
++        break;
++    case BUTTON_TITLE_NO:
++        aLabel.AssignLiteral(GTK_STOCK_NO);
++        break;
++    case BUTTON_TITLE_SAVE:
++        aLabel.AssignLiteral(GTK_STOCK_SAVE);
++        break;
++    case BUTTON_TITLE_DONT_SAVE:
++        aLabel.AssignLiteral("Don't Save");
++        break;
++    case BUTTON_TITLE_REVERT:
++        aLabel.AssignLiteral("Revert");
++        break;
++    case BUTTON_TITLE_IS_STRING:
++        aLabel = aStringValue;
++        break;
++    default:
++        NS_WARNING("Unexpected button flags");
++    }
++}
+diff --git a/embedding/browser/gtk/src/GtkPromptService.h b/embedding/browser/gtk/src/GtkPromptService.h
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/src/GtkPromptService.h
+@@ -0,0 +1,59 @@
++/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
++/* vim:expandtab:shiftwidth=4:tabstop=4: */
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * Netscape Communications Corporation.
++ * Portions created by the Initial Developer are Copyright (C) 2003
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *  Brian Ryner <[email protected]>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#include "nsIPromptService.h"
++#include "nsStringGlue.h"
++#include <gtk/gtk.h>
++
++class nsIDOMWindow;
++
++class GtkPromptService : public nsIPromptService
++{
++public:
++    GtkPromptService();
++    virtual ~GtkPromptService();
++
++    NS_DECL_ISUPPORTS
++    NS_DECL_NSIPROMPTSERVICE
++
++private:
++    GtkWindow* GetGtkWindowForDOMWindow(nsIDOMWindow* aDOMWindow);
++    void GetButtonLabel(PRUint32 aFlags, PRUint32 aPos,
++                        const PRUnichar* aStringValue, nsAString &aLabel);
++};
+diff --git a/embedding/browser/gtk/src/Makefile.in b/embedding/browser/gtk/src/Makefile.in
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/src/Makefile.in
+@@ -0,0 +1,112 @@
++# 
++# ***** BEGIN LICENSE BLOCK *****
++# Version: MPL 1.1/GPL 2.0/LGPL 2.1
++#
++# The contents of this file are subject to the Mozilla Public License Version
++# 1.1 (the "License"); you may not use this file except in compliance with
++# the License. You may obtain a copy of the License at
++# http://www.mozilla.org/MPL/
++#
++# Software distributed under the License is distributed on an "AS IS" basis,
++# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++# for the specific language governing rights and limitations under the
++# License.
++#
++# The Original Code is the Mozilla browser.
++#
++# The Initial Developer of the Original Code is
++# Christopher Blizzard.
++# Portions created by the Initial Developer are Copyright (C) 1999
++# the Initial Developer. All Rights Reserved.
++#
++# Contributor(s):
++#   Christopher Blizzard <[email protected]>
++#
++# Alternatively, the contents of this file may be used under the terms of
++# either the GNU General Public License Version 2 or later (the "GPL"), or
++# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++# in which case the provisions of the GPL or the LGPL are applicable instead
++# of those above. If you wish to allow use of your version of this file only
++# under the terms of either the GPL or the LGPL, and not to allow others to
++# use your version of this file under the terms of the MPL, indicate your
++# decision by deleting the provisions above and replace them with the notice
++# and other provisions required by the GPL or the LGPL. If you do not delete
++# the provisions above, a recipient may use your version of this file under
++# the terms of any one of the MPL, the GPL or the LGPL.
++#
++# ***** END LICENSE BLOCK *****
++
++DEPTH		= ../../../..
++topsrcdir	= @top_srcdir@
++srcdir		= @srcdir@
++VPATH		= @srcdir@
++
++include $(DEPTH)/config/autoconf.mk
++
++MODULE		= gtkembedmoz
++LIBRARY_NAME	= gtkembedmoz
++LIBXUL_LIBRARY	= 1
++FORCE_STATIC_LIB = 1
++DEFINES += -DIMPL_XREAPI
++
++
++
++CPPSRCS		= \
++		gtkmozembed2.cpp \
++		EmbedPrivate.cpp \
++		EmbedWindow.cpp \
++		EmbedProgress.cpp \
++		EmbedContentListener.cpp \
++		EmbedEventListener.cpp \
++		EmbedWindowCreator.cpp \
++		$(NULL)
++
++ifdef MOZ_ENABLE_GTK2
++CSRCS           = \
++		gtkmozembedmarshal.c
++CPPSRCS         += \
++		EmbedPrompter.cpp \
++		GtkPromptService.cpp
++endif
++
++LOCAL_INCLUDES += \
++		  -I. \
++		  $(NULL)
++
++include $(topsrcdir)/config/config.mk
++
++EXPORTS		= \
++		gtkmozembed.h \
++		gtkmozembed_glue.cpp \
++		gtkmozembed_internal.h
++
++include $(topsrcdir)/config/rules.mk
++
++ifeq ($(OS_ARCH), SunOS)
++ifndef GNU_CC
++# When using Sun's WorkShop compiler, including
++# /wherever/workshop-5.0/SC5.0/include/CC/std/time.h
++# causes most of these compiles to fail with:
++# line 29: Error: Multiple declaration for std::tm.
++# So, this gets around the problem.
++DEFINES         += -D_TIME_H=1
++endif
++endif
++
++CXXFLAGS        += $(MOZ_GTK_CFLAGS) $(MOZ_GTK2_CFLAGS)
++CFLAGS          += $(MOZ_GTK_CFLAGS) $(MOZ_GTK2_CFLAGS)
++DEFINES         += -D_IMPL_GTKMOZEMBED
++
++MARSHAL_FILE = gtkmozembedmarshal
++MARSHAL_PREFIX = gtkmozembed
++
++$(MARSHAL_FILE).h: $(MARSHAL_FILE).list
++	glib-genmarshal --prefix=$(MARSHAL_PREFIX) $(srcdir)/$(MARSHAL_FILE).list --skip-source --header > $@
++
++$(MARSHAL_FILE).c: $(MARSHAL_FILE).list $(MARSHAL_FILE).h
++	glib-genmarshal --prefix=$(MARSHAL_PREFIX) $(srcdir)/$(MARSHAL_FILE).list --skip-source --body > $@
++
++gtkmozembed2.$(OBJ_SUFFIX): $(MARSHAL_FILE).h
++
++GARBAGE += $(MARSHAL_FILE).h $(MARSHAL_FILE).c
++
+diff --git a/embedding/browser/gtk/src/gtkmozembed.h b/embedding/browser/gtk/src/gtkmozembed.h
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/src/gtkmozembed.h
+@@ -0,0 +1,287 @@
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * Christopher Blizzard.
++ * Portions created by the Initial Developer are Copyright (C) 2001
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *   Christopher Blizzard <[email protected]>
++ *   Ramiro Estrugo <[email protected]>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#ifndef gtkmozembed_h
++#define gtkmozembed_h
++
++#include <stddef.h>
++#include <gtk/gtk.h>
++
++#ifdef MOZILLA_CLIENT
++#include "nscore.h"
++#else /* MOZILLA_CLIENT */
++#ifndef nscore_h__
++/* Because this header may be included from files which not part of the mozilla
++   build system, define macros from nscore.h */
++
++#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
++#define NS_HIDDEN __attribute__((visibility("hidden")))
++#else
++#define NS_HIDDEN
++#endif
++
++#define NS_FROZENCALL
++#define NS_EXPORT_(type) type
++#define NS_IMPORT_(type) type
++#endif /* nscore_h__ */
++#endif /* MOZILLA_CLIENT */
++
++#ifdef XPCOM_GLUE
++
++#define GTKMOZEMBED_API(type, name, params) \
++  typedef type (NS_FROZENCALL * name##Type) params; \
++  extern name##Type name NS_HIDDEN;
++
++#else /* XPCOM_GLUE */
++
++#ifdef _IMPL_GTKMOZEMBED
++#define GTKMOZEMBED_API(type, name, params) NS_EXPORT_(type) name params;
++#else
++#define GTKMOZEMBED_API(type,name, params) NS_IMPORT_(type) name params;
++#endif
++
++#endif /* XPCOM_GLUE */
++
++#ifdef __cplusplus
++extern "C" {
++#endif /* __cplusplus */
++
++#define GTK_TYPE_MOZ_EMBED             (gtk_moz_embed_get_type())
++#define GTK_MOZ_EMBED(obj)             G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_MOZ_EMBED, GtkMozEmbed)
++#define GTK_MOZ_EMBED_CLASS(klass)     G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_MOZ_EMBED, GtkMozEmbedClass)
++#define GTK_IS_MOZ_EMBED(obj)          G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_MOZ_EMBED)
++#define GTK_IS_MOZ_EMBED_CLASS(klass)  G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_MOZ_EMBED)
++
++typedef struct _GtkMozEmbed      GtkMozEmbed;
++typedef struct _GtkMozEmbedClass GtkMozEmbedClass;
++
++struct _GtkMozEmbed
++{
++  GtkBin    bin;
++  void     *data;
++};
++
++struct _GtkMozEmbedClass
++{
++  GtkBinClass parent_class;
++
++  void (* link_message)        (GtkMozEmbed *embed);
++  void (* js_status)           (GtkMozEmbed *embed);
++  void (* location)            (GtkMozEmbed *embed);
++  void (* title)               (GtkMozEmbed *embed);
++  void (* progress)            (GtkMozEmbed *embed, gint curprogress,
++                                gint maxprogress);
++  void (* progress_all)        (GtkMozEmbed *embed, const char *aURI,
++                                gint curprogress, gint maxprogress);
++  void (* net_state)           (GtkMozEmbed *embed, gint state, guint status);
++  void (* net_state_all)       (GtkMozEmbed *embed, const char *aURI,
++                                gint state, guint status);
++  void (* net_start)           (GtkMozEmbed *embed);
++  void (* net_stop)            (GtkMozEmbed *embed);
++  void (* new_window)          (GtkMozEmbed *embed, GtkMozEmbed **newEmbed,
++                                guint chromemask);
++  void (* visibility)          (GtkMozEmbed *embed, gboolean visibility);
++  void (* destroy_brsr)        (GtkMozEmbed *embed);
++  gint (* open_uri)            (GtkMozEmbed *embed, const char *aURI);
++  void (* size_to)             (GtkMozEmbed *embed, gint width, gint height);
++  gint (* dom_key_down)        (GtkMozEmbed *embed, gpointer dom_event);
++  gint (* dom_key_press)       (GtkMozEmbed *embed, gpointer dom_event);
++  gint (* dom_key_up)          (GtkMozEmbed *embed, gpointer dom_event);
++  gint (* dom_mouse_down)      (GtkMozEmbed *embed, gpointer dom_event);
++  gint (* dom_mouse_up)        (GtkMozEmbed *embed, gpointer dom_event);
++  gint (* dom_mouse_click)     (GtkMozEmbed *embed, gpointer dom_event);
++  gint (* dom_mouse_dbl_click) (GtkMozEmbed *embed, gpointer dom_event);
++  gint (* dom_mouse_over)      (GtkMozEmbed *embed, gpointer dom_event);
++  gint (* dom_mouse_out)       (GtkMozEmbed *embed, gpointer dom_event);
++  void (* security_change)     (GtkMozEmbed *embed, gpointer request,
++                                guint state);
++  void (* status_change)       (GtkMozEmbed *embed, gpointer request,
++                                gint status, gpointer message);
++  gint (* dom_activate)        (GtkMozEmbed *embed, gpointer dom_event);
++  gint (* dom_focus_in)        (GtkMozEmbed *embed, gpointer dom_event);
++  gint (* dom_focus_out)       (GtkMozEmbed *embed, gpointer dom_event);
++};
++
++GTKMOZEMBED_API(GType,      gtk_moz_embed_get_type,        (void))
++GTKMOZEMBED_API(GtkWidget*, gtk_moz_embed_new,             (void))
++GTKMOZEMBED_API(void,       gtk_moz_embed_push_startup,    (void))
++GTKMOZEMBED_API(void,       gtk_moz_embed_pop_startup,     (void))
++
++/* Tell gtkmozembed where the gtkmozembed libs live. If this is not specified,
++   The MOZILLA_FIVE_HOME environment variable is checked. */
++GTKMOZEMBED_API(void,       gtk_moz_embed_set_path,        (const char *aPath))
++
++GTKMOZEMBED_API(void,       gtk_moz_embed_set_comp_path,   (const char *aPath))
++GTKMOZEMBED_API(void,      gtk_moz_embed_set_profile_path, (const char *aDir,
++                                                            const char *aName))
++GTKMOZEMBED_API(void,      gtk_moz_embed_load_url,        (GtkMozEmbed *embed,
++                                                           const char *url))
++GTKMOZEMBED_API(void,      gtk_moz_embed_stop_load,       (GtkMozEmbed *embed))
++GTKMOZEMBED_API(gboolean,  gtk_moz_embed_can_go_back,     (GtkMozEmbed *embed))
++GTKMOZEMBED_API(gboolean,  gtk_moz_embed_can_go_forward,  (GtkMozEmbed *embed))
++GTKMOZEMBED_API(void,      gtk_moz_embed_go_back,         (GtkMozEmbed *embed))
++GTKMOZEMBED_API(void,      gtk_moz_embed_go_forward,      (GtkMozEmbed *embed))
++GTKMOZEMBED_API(void,   gtk_moz_embed_render_data,     (GtkMozEmbed *embed, 
++                                                        const char *data,
++                                                        guint32 len,
++                                                        const char *base_uri, 
++                                                        const char *mime_type))
++GTKMOZEMBED_API(void,   gtk_moz_embed_open_stream,     (GtkMozEmbed *embed,
++                                                        const char *base_uri,
++                                                        const char *mime_type))
++GTKMOZEMBED_API(void,   gtk_moz_embed_append_data,      (GtkMozEmbed *embed,
++                                                         const char *data,
++                                                         guint32 len))
++GTKMOZEMBED_API(void,   gtk_moz_embed_close_stream,     (GtkMozEmbed *embed))
++GTKMOZEMBED_API(char*,  gtk_moz_embed_get_link_message, (GtkMozEmbed *embed))
++GTKMOZEMBED_API(char*,  gtk_moz_embed_get_js_status,    (GtkMozEmbed *embed))
++GTKMOZEMBED_API(char*,  gtk_moz_embed_get_title,        (GtkMozEmbed *embed))
++GTKMOZEMBED_API(char*,  gtk_moz_embed_get_location,     (GtkMozEmbed *embed))
++GTKMOZEMBED_API(void,   gtk_moz_embed_reload,           (GtkMozEmbed *embed,
++                                                         gint32 flags))
++GTKMOZEMBED_API(void,   gtk_moz_embed_set_chrome_mask,  (GtkMozEmbed *embed, 
++                                                         guint32 flags))
++GTKMOZEMBED_API(guint32, gtk_moz_embed_get_chrome_mask, (GtkMozEmbed *embed))
++
++/* These are straight out of nsIWebProgressListener.h */
++
++typedef enum
++{
++  GTK_MOZ_EMBED_FLAG_START = 1,
++  GTK_MOZ_EMBED_FLAG_REDIRECTING = 2,
++  GTK_MOZ_EMBED_FLAG_TRANSFERRING = 4,
++  GTK_MOZ_EMBED_FLAG_NEGOTIATING = 8,
++  GTK_MOZ_EMBED_FLAG_STOP = 16,
++  
++  GTK_MOZ_EMBED_FLAG_IS_REQUEST = 65536,
++  GTK_MOZ_EMBED_FLAG_IS_DOCUMENT = 131072,
++  GTK_MOZ_EMBED_FLAG_IS_NETWORK = 262144,
++  GTK_MOZ_EMBED_FLAG_IS_WINDOW = 524288,
++
++  GTK_MOZ_EMBED_FLAG_RESTORING = 16777216
++} GtkMozEmbedProgressFlags;
++
++/* These are from various networking headers */
++
++typedef enum
++{
++  /* NS_ERROR_UNKNOWN_HOST */
++  GTK_MOZ_EMBED_STATUS_FAILED_DNS     = 2152398878U,
++ /* NS_ERROR_CONNECTION_REFUSED */
++  GTK_MOZ_EMBED_STATUS_FAILED_CONNECT = 2152398861U,
++ /* NS_ERROR_NET_TIMEOUT */
++  GTK_MOZ_EMBED_STATUS_FAILED_TIMEOUT = 2152398862U,
++ /* NS_BINDING_ABORTED */
++  GTK_MOZ_EMBED_STATUS_FAILED_USERCANCELED = 2152398850U
++} GtkMozEmbedStatusFlags;
++
++/* 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 
++{
++  GTK_MOZ_EMBED_FLAG_RELOADNORMAL = 0,
++  GTK_MOZ_EMBED_FLAG_RELOADBYPASSCACHE = 1,
++  GTK_MOZ_EMBED_FLAG_RELOADBYPASSPROXY = 2,
++  GTK_MOZ_EMBED_FLAG_RELOADBYPASSPROXYANDCACHE = 3,
++  GTK_MOZ_EMBED_FLAG_RELOADCHARSETCHANGE = 4
++} GtkMozEmbedReloadFlags;
++
++/* These are straight out of nsIWebBrowserChrome.h */
++
++typedef enum
++{
++  GTK_MOZ_EMBED_FLAG_DEFAULTCHROME = 1U,
++  GTK_MOZ_EMBED_FLAG_WINDOWBORDERSON = 2U,
++  GTK_MOZ_EMBED_FLAG_WINDOWCLOSEON = 4U,
++  GTK_MOZ_EMBED_FLAG_WINDOWRESIZEON = 8U,
++  GTK_MOZ_EMBED_FLAG_MENUBARON = 16U,
++  GTK_MOZ_EMBED_FLAG_TOOLBARON = 32U,
++  GTK_MOZ_EMBED_FLAG_LOCATIONBARON = 64U,
++  GTK_MOZ_EMBED_FLAG_STATUSBARON = 128U,
++  GTK_MOZ_EMBED_FLAG_PERSONALTOOLBARON = 256U,
++  GTK_MOZ_EMBED_FLAG_SCROLLBARSON = 512U,
++  GTK_MOZ_EMBED_FLAG_TITLEBARON = 1024U,
++  GTK_MOZ_EMBED_FLAG_EXTRACHROMEON = 2048U,
++  GTK_MOZ_EMBED_FLAG_ALLCHROME = 4094U,
++  GTK_MOZ_EMBED_FLAG_WINDOWRAISED = 33554432U,
++  GTK_MOZ_EMBED_FLAG_WINDOWLOWERED = 67108864U,
++  GTK_MOZ_EMBED_FLAG_CENTERSCREEN = 134217728U,
++  GTK_MOZ_EMBED_FLAG_DEPENDENT = 268435456U,
++  GTK_MOZ_EMBED_FLAG_MODAL = 536870912U,
++  GTK_MOZ_EMBED_FLAG_OPENASDIALOG = 1073741824U,
++  GTK_MOZ_EMBED_FLAG_OPENASCHROME = 2147483648U 
++} GtkMozEmbedChromeFlags;
++
++/* this is a singleton object that you can hook up to to get signals
++   that are not handed out on a per widget basis. */
++
++#define GTK_TYPE_MOZ_EMBED_SINGLE            (gtk_moz_embed_single_get_type())
++#define GTK_MOZ_EMBED_SINGLE(obj)            GTK_CHECK_CAST((obj), GTK_TYPE_MOZ_EMBED_SINGLE, GtkMozEmbedSingle)
++#define GTK_MOZ_EMBED_SINGLE_CLASS(klass)    GTK_CHEK_CLASS_CAST((klass), GTK_TYPE_MOZ_EMBED_SINGLE, GtkMozEmbedSingleClass)
++#define GTK_IS_MOZ_EMBED_SINGLE(obj)         GTK_CHECK_TYPE((obj), GTK_TYPE_MOZ_EMBED_SINGLE)
++#define GTK_IS_MOZ_EMBED_SINGLE_CLASS(klass) GTK_CHECK_CLASS_TYPE((klass), GTK_TYPE_MOZ_EMBED)
++#define GTK_MOZ_EMBED_SINGLE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_MOZ_EMBED_SINGLE, GtkMozEmbedSingleClass))
++
++typedef struct _GtkMozEmbedSingle      GtkMozEmbedSingle;
++typedef struct _GtkMozEmbedSingleClass GtkMozEmbedSingleClass;
++
++struct _GtkMozEmbedSingle
++{
++  GtkObject  object;
++  void      *data;
++};
++
++struct _GtkMozEmbedSingleClass
++{
++  GtkObjectClass parent_class;
++
++  void (* new_window_orphan)   (GtkMozEmbedSingle *embed,
++                                GtkMozEmbed **newEmbed,
++                                guint chromemask);
++};
++
++GTKMOZEMBED_API(GType,               gtk_moz_embed_single_get_type, (void))
++GTKMOZEMBED_API(GtkMozEmbedSingle *, gtk_moz_embed_single_get,      (void))
++
++#ifdef __cplusplus
++}
++#endif /* __cplusplus */
++
++#endif /* gtkmozembed_h */
+diff --git a/embedding/browser/gtk/src/gtkmozembed2.cpp b/embedding/browser/gtk/src/gtkmozembed2.cpp
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/src/gtkmozembed2.cpp
+@@ -0,0 +1,1132 @@
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright (C) Christopher Blizzard.  All Rights Reserved.
++ * Portions created by the Initial Developer are Copyright (C) 2001
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *   Christopher Blizzard <[email protected]>
++ *   Ramiro Estrugo <[email protected]>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#include <stdio.h>
++
++#include "gtkmozembed.h"
++#include "gtkmozembedprivate.h"
++#include "gtkmozembed_internal.h"
++
++#include "EmbedPrivate.h"
++#include "EmbedWindow.h"
++
++// so we can do our get_nsIWebBrowser later...
++#include "nsIWebBrowser.h"
++
++#include "gtkmozembedmarshal.h"
++
++#define NEW_TOOLKIT_STRING(x) g_strdup(NS_ConvertUTF16toUTF8(x).get())
++#define GET_OBJECT_CLASS_TYPE(x) G_OBJECT_CLASS_TYPE(x)
++
++class nsIDirectoryServiceProvider;
++
++// class and instance initialization
++
++static void
++gtk_moz_embed_class_init(GtkMozEmbedClass *klass);
++
++static void
++gtk_moz_embed_init(GtkMozEmbed *embed);
++
++// GtkObject methods
++
++static void
++gtk_moz_embed_destroy(GtkObject *object);
++
++// GtkWidget methods
++
++static void
++gtk_moz_embed_realize(GtkWidget *widget);
++
++static void
++gtk_moz_embed_unrealize(GtkWidget *widget);
++
++static void
++gtk_moz_embed_size_allocate(GtkWidget *widget, GtkAllocation *allocation);
++
++static void
++gtk_moz_embed_map(GtkWidget *widget);
++
++static void
++gtk_moz_embed_unmap(GtkWidget *widget);
++
++#ifdef MOZ_ACCESSIBILITY_ATK
++static AtkObject* gtk_moz_embed_get_accessible (GtkWidget *widget);
++#endif
++
++static gint
++handle_child_focus_in(GtkWidget     *aWidget,
++		      GdkEventFocus *aGdkFocusEvent,
++		      GtkMozEmbed   *aEmbed);
++
++static gint
++handle_child_focus_out(GtkWidget     *aWidget,
++		       GdkEventFocus *aGdkFocusEvent,
++		       GtkMozEmbed   *aEmbed);
++
++// globals for this type of widget
++
++static GtkBinClass *embed_parent_class;
++
++guint moz_embed_signals[EMBED_LAST_SIGNAL] = { 0 };
++
++// GtkObject + class-related functions
++
++GType
++gtk_moz_embed_get_type(void)
++{
++  static GType moz_embed_type = 0;
++  if (moz_embed_type == 0)
++  {
++    const GTypeInfo our_info =
++    {
++      sizeof(GtkMozEmbedClass),
++      NULL, /* base_init */
++      NULL, /* base_finalize */
++      (GClassInitFunc)gtk_moz_embed_class_init,
++      NULL,
++      NULL, /* class_data */
++      sizeof(GtkMozEmbed),
++      0, /* n_preallocs */
++      (GInstanceInitFunc)gtk_moz_embed_init,
++    };
++
++    moz_embed_type = g_type_register_static(GTK_TYPE_BIN,
++                                            "GtkMozEmbed",
++                                            &our_info,
++                                            (GTypeFlags)0);
++  }
++
++  return moz_embed_type;
++}
++
++static void
++gtk_moz_embed_class_init(GtkMozEmbedClass *klass)
++{
++  GtkContainerClass  *container_class;
++  GtkWidgetClass     *widget_class;
++  GtkObjectClass     *object_class;
++
++  container_class = GTK_CONTAINER_CLASS(klass);
++  widget_class    = GTK_WIDGET_CLASS(klass);
++  object_class    = GTK_OBJECT_CLASS(klass);
++
++  embed_parent_class = (GtkBinClass *)g_type_class_peek(gtk_bin_get_type());
++
++  widget_class->realize = gtk_moz_embed_realize;
++  widget_class->unrealize = gtk_moz_embed_unrealize;
++  widget_class->size_allocate = gtk_moz_embed_size_allocate;
++  widget_class->map = gtk_moz_embed_map;
++  widget_class->unmap = gtk_moz_embed_unmap;
++
++#ifdef MOZ_ACCESSIBILITY_ATK
++  widget_class->get_accessible = gtk_moz_embed_get_accessible;
++#endif
++
++  object_class->destroy = gtk_moz_embed_destroy;
++
++  // set up our signals
++
++  moz_embed_signals[LINK_MESSAGE] =
++    g_signal_new("link_message",
++                 G_TYPE_FROM_CLASS(klass),
++                 G_SIGNAL_RUN_FIRST,
++                 G_STRUCT_OFFSET(GtkMozEmbedClass, link_message),
++                 NULL, NULL,
++                 g_cclosure_marshal_VOID__VOID,
++                 G_TYPE_NONE, 0);
++  moz_embed_signals[JS_STATUS] =
++    g_signal_new("js_status",
++                 G_TYPE_FROM_CLASS(klass),
++                 G_SIGNAL_RUN_FIRST,
++                 G_STRUCT_OFFSET(GtkMozEmbedClass, js_status),
++                 NULL, NULL,
++                 g_cclosure_marshal_VOID__VOID,
++                 G_TYPE_NONE, 0);
++  moz_embed_signals[LOCATION] =
++    g_signal_new("location",
++                 G_TYPE_FROM_CLASS(klass),
++                 G_SIGNAL_RUN_FIRST,
++                 G_STRUCT_OFFSET(GtkMozEmbedClass, location),
++                 NULL, NULL,
++                 g_cclosure_marshal_VOID__VOID,
++                 G_TYPE_NONE, 0);
++  moz_embed_signals[TITLE] =
++    g_signal_new("title",
++                 G_TYPE_FROM_CLASS(klass),
++                 G_SIGNAL_RUN_FIRST,
++                 G_STRUCT_OFFSET(GtkMozEmbedClass, title),
++                 NULL, NULL,
++                 g_cclosure_marshal_VOID__VOID,
++                 G_TYPE_NONE, 0);
++  moz_embed_signals[PROGRESS] =
++    g_signal_new("progress",
++                 G_TYPE_FROM_CLASS(klass),
++                 G_SIGNAL_RUN_FIRST,
++                 G_STRUCT_OFFSET(GtkMozEmbedClass, progress),
++                 NULL, NULL,
++                 gtkmozembed_VOID__INT_INT,
++                 G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);
++  moz_embed_signals[PROGRESS_ALL] =
++    g_signal_new("progress_all",
++                 G_TYPE_FROM_CLASS(klass),
++                 G_SIGNAL_RUN_FIRST,
++                 G_STRUCT_OFFSET(GtkMozEmbedClass, progress_all),
++                 NULL, NULL,
++                 gtkmozembed_VOID__STRING_INT_INT,
++                 G_TYPE_NONE, 3,
++                 G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE,
++                 G_TYPE_INT, G_TYPE_INT);
++  moz_embed_signals[NET_STATE] =
++    g_signal_new("net_state",
++                 G_TYPE_FROM_CLASS(klass),
++                 G_SIGNAL_RUN_FIRST,
++                 G_STRUCT_OFFSET(GtkMozEmbedClass, net_state),
++                 NULL, NULL,
++                 gtkmozembed_VOID__INT_UINT,
++                 G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_UINT);
++  moz_embed_signals[NET_STATE_ALL] =
++    g_signal_new("net_state_all",
++                 G_TYPE_FROM_CLASS(klass),
++                 G_SIGNAL_RUN_FIRST,
++                 G_STRUCT_OFFSET(GtkMozEmbedClass, net_state_all),
++                 NULL, NULL,
++                 gtkmozembed_VOID__STRING_INT_UINT,
++                 G_TYPE_NONE, 3,
++                 G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE,
++                 G_TYPE_INT, G_TYPE_UINT);
++  moz_embed_signals[NET_START] =
++    g_signal_new("net_start",
++                 G_TYPE_FROM_CLASS(klass),
++                 G_SIGNAL_RUN_FIRST,
++                 G_STRUCT_OFFSET(GtkMozEmbedClass, net_start),
++                 NULL, NULL,
++                 g_cclosure_marshal_VOID__VOID,
++                 G_TYPE_NONE, 0);
++  moz_embed_signals[NET_STOP] =
++    g_signal_new("net_stop",
++                 G_TYPE_FROM_CLASS(klass),
++                 G_SIGNAL_RUN_FIRST,
++                 G_STRUCT_OFFSET(GtkMozEmbedClass, net_stop),
++                 NULL, NULL,
++                 g_cclosure_marshal_VOID__VOID,
++                 G_TYPE_NONE, 0);
++  moz_embed_signals[NEW_WINDOW] =
++    g_signal_new("new_window",
++                 G_TYPE_FROM_CLASS(klass),
++                 G_SIGNAL_RUN_FIRST,
++                 G_STRUCT_OFFSET(GtkMozEmbedClass, new_window),
++                 NULL, NULL,
++                 gtkmozembed_VOID__POINTER_UINT,
++                 G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_UINT);
++  moz_embed_signals[VISIBILITY] =
++    g_signal_new("visibility",
++                 G_TYPE_FROM_CLASS(klass),
++                 G_SIGNAL_RUN_FIRST,
++                 G_STRUCT_OFFSET(GtkMozEmbedClass, visibility),
++                 NULL, NULL,
++                 g_cclosure_marshal_VOID__BOOLEAN,
++                 G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
++  moz_embed_signals[DESTROY_BROWSER] =
++    g_signal_new("destroy_browser",
++                 G_TYPE_FROM_CLASS(klass),
++                 G_SIGNAL_RUN_FIRST,
++                 G_STRUCT_OFFSET(GtkMozEmbedClass, destroy_brsr),
++                 NULL, NULL,
++                 g_cclosure_marshal_VOID__VOID,
++                 G_TYPE_NONE, 0);
++  moz_embed_signals[OPEN_URI] =
++    g_signal_new("open_uri",
++                 G_TYPE_FROM_CLASS(klass),
++                 G_SIGNAL_RUN_LAST,
++                 G_STRUCT_OFFSET(GtkMozEmbedClass, open_uri),
++                 NULL, NULL,
++                 gtkmozembed_BOOL__STRING,
++                 G_TYPE_BOOLEAN, 1, G_TYPE_STRING |
++                 G_SIGNAL_TYPE_STATIC_SCOPE);
++  moz_embed_signals[SIZE_TO] =
++    g_signal_new("size_to",
++                 G_TYPE_FROM_CLASS(klass),
++                 G_SIGNAL_RUN_LAST,
++                 G_STRUCT_OFFSET(GtkMozEmbedClass, size_to),
++                 NULL, NULL,
++                 gtkmozembed_VOID__INT_INT,
++                 G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);
++  moz_embed_signals[DOM_KEY_DOWN] =
++    g_signal_new("dom_key_down",
++                 G_TYPE_FROM_CLASS(klass),
++                 G_SIGNAL_RUN_LAST,
++                 G_STRUCT_OFFSET(GtkMozEmbedClass, dom_key_down),
++                 NULL, NULL,
++                 gtkmozembed_BOOL__POINTER,
++                 G_TYPE_BOOLEAN, 1, G_TYPE_POINTER);
++  moz_embed_signals[DOM_KEY_PRESS] =
++    g_signal_new("dom_key_press",
++                 G_TYPE_FROM_CLASS(klass),
++                 G_SIGNAL_RUN_LAST,
++                 G_STRUCT_OFFSET(GtkMozEmbedClass, dom_key_press),
++                 NULL, NULL,
++                 gtkmozembed_BOOL__POINTER,
++                 G_TYPE_BOOLEAN, 1, G_TYPE_POINTER);
++  moz_embed_signals[DOM_KEY_UP] =
++    g_signal_new("dom_key_up",
++                 G_TYPE_FROM_CLASS(klass),
++                 G_SIGNAL_RUN_LAST,
++                 G_STRUCT_OFFSET(GtkMozEmbedClass, dom_key_up),
++                 NULL, NULL,
++                 gtkmozembed_BOOL__POINTER,
++                 G_TYPE_BOOLEAN, 1, G_TYPE_POINTER);
++  moz_embed_signals[DOM_MOUSE_DOWN] =
++    g_signal_new("dom_mouse_down",
++                 G_TYPE_FROM_CLASS(klass),
++                 G_SIGNAL_RUN_LAST,
++                 G_STRUCT_OFFSET(GtkMozEmbedClass, dom_mouse_down),
++                 NULL, NULL,
++                 gtkmozembed_BOOL__POINTER,
++                 G_TYPE_BOOLEAN, 1, G_TYPE_POINTER);
++  moz_embed_signals[DOM_MOUSE_UP] =
++    g_signal_new("dom_mouse_up",
++                 G_TYPE_FROM_CLASS(klass),
++                 G_SIGNAL_RUN_LAST,
++                 G_STRUCT_OFFSET(GtkMozEmbedClass, dom_mouse_up),
++                 NULL, NULL,
++                 gtkmozembed_BOOL__POINTER,
++                 G_TYPE_BOOLEAN, 1, G_TYPE_POINTER);
++  moz_embed_signals[DOM_MOUSE_CLICK] =
++    g_signal_new("dom_mouse_click",
++                 G_TYPE_FROM_CLASS(klass),
++                 G_SIGNAL_RUN_LAST,
++                 G_STRUCT_OFFSET(GtkMozEmbedClass, dom_mouse_click),
++                 NULL, NULL,
++                 gtkmozembed_BOOL__POINTER,
++                 G_TYPE_BOOLEAN, 1, G_TYPE_POINTER);
++  moz_embed_signals[DOM_MOUSE_DBL_CLICK] =
++    g_signal_new("dom_mouse_dbl_click",
++                 G_TYPE_FROM_CLASS(klass),
++                 G_SIGNAL_RUN_LAST,
++                 G_STRUCT_OFFSET(GtkMozEmbedClass, dom_mouse_dbl_click),
++                 NULL, NULL,
++                 gtkmozembed_BOOL__POINTER,
++                 G_TYPE_BOOLEAN, 1, G_TYPE_POINTER);
++  moz_embed_signals[DOM_MOUSE_OVER] =
++    g_signal_new("dom_mouse_over",
++                 G_TYPE_FROM_CLASS(klass),
++                 G_SIGNAL_RUN_LAST,
++                 G_STRUCT_OFFSET(GtkMozEmbedClass, dom_mouse_over),
++                 NULL, NULL,
++                 gtkmozembed_BOOL__POINTER,
++                 G_TYPE_BOOLEAN, 1, G_TYPE_POINTER);
++  moz_embed_signals[DOM_MOUSE_OUT] =
++    g_signal_new("dom_mouse_out",
++                 G_TYPE_FROM_CLASS(klass),
++                 G_SIGNAL_RUN_LAST,
++                 G_STRUCT_OFFSET(GtkMozEmbedClass, dom_mouse_out),
++                 NULL, NULL,
++                 gtkmozembed_BOOL__POINTER,
++                 G_TYPE_BOOLEAN, 1, G_TYPE_POINTER);
++  moz_embed_signals[SECURITY_CHANGE] =
++    g_signal_new("security_change",
++                 G_TYPE_FROM_CLASS(klass),
++                 G_SIGNAL_RUN_LAST,
++                 G_STRUCT_OFFSET(GtkMozEmbedClass, security_change),
++                 NULL, NULL,
++                 gtkmozembed_VOID__POINTER_UINT,
++                 G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_UINT);
++  moz_embed_signals[STATUS_CHANGE] =
++    g_signal_new("status_change",
++                 G_TYPE_FROM_CLASS(klass),
++                 G_SIGNAL_RUN_LAST,
++                 G_STRUCT_OFFSET(GtkMozEmbedClass, status_change),
++                 NULL, NULL,
++                 gtkmozembed_VOID__POINTER_INT_POINTER,
++                 G_TYPE_NONE, 3,
++                 G_TYPE_POINTER, G_TYPE_INT, G_TYPE_POINTER);
++  moz_embed_signals[DOM_ACTIVATE] =
++    g_signal_new("dom_activate",
++                 G_TYPE_FROM_CLASS(klass),
++                 G_SIGNAL_RUN_LAST,
++                 G_STRUCT_OFFSET(GtkMozEmbedClass, dom_activate),
++                 NULL, NULL,
++                 gtkmozembed_BOOL__POINTER,
++                 G_TYPE_BOOLEAN, 1, G_TYPE_POINTER);
++  moz_embed_signals[DOM_FOCUS_IN] =
++    g_signal_new("dom_focus_in",
++                 G_TYPE_FROM_CLASS(klass),
++                 G_SIGNAL_RUN_LAST,
++                 G_STRUCT_OFFSET(GtkMozEmbedClass, dom_focus_in),
++                 NULL, NULL,
++                 gtkmozembed_BOOL__POINTER,
++                 G_TYPE_BOOLEAN, 1, G_TYPE_POINTER);
++  moz_embed_signals[DOM_FOCUS_OUT] =
++    g_signal_new("dom_focus_out",
++                 G_TYPE_FROM_CLASS(klass),
++                 G_SIGNAL_RUN_LAST,
++                 G_STRUCT_OFFSET(GtkMozEmbedClass, dom_focus_out),
++                 NULL, NULL,
++                 gtkmozembed_BOOL__POINTER,
++                 G_TYPE_BOOLEAN, 1, G_TYPE_POINTER);
++}
++
++static void
++gtk_moz_embed_init(GtkMozEmbed *embed)
++{
++  EmbedPrivate *priv = new EmbedPrivate();
++  embed->data = priv;
++  gtk_widget_set_name(GTK_WIDGET(embed), "gtkmozembed");
++
++  GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(embed), GTK_NO_WINDOW);
++}
++
++GtkWidget *
++gtk_moz_embed_new(void)
++{
++  return GTK_WIDGET(g_object_new(GTK_TYPE_MOZ_EMBED, NULL));
++}
++
++// GtkObject methods
++
++static void
++gtk_moz_embed_destroy(GtkObject *object)
++{
++  GtkMozEmbed  *embed;
++  EmbedPrivate *embedPrivate;
++  
++  g_return_if_fail(object != NULL);
++  g_return_if_fail(GTK_IS_MOZ_EMBED(object));
++
++  embed = GTK_MOZ_EMBED(object);
++  embedPrivate = (EmbedPrivate *)embed->data;
++
++  if (embedPrivate) {
++
++    // Destroy the widget only if it's been Init()ed.
++    if(embedPrivate->mMozWindowWidget != 0) {
++      embedPrivate->Destroy();
++    }
++
++    delete embedPrivate;
++    embed->data = NULL;
++  }
++}
++
++// GtkWidget methods
++
++static void
++gtk_moz_embed_realize(GtkWidget *widget)
++{
++  GtkMozEmbed    *embed;
++  EmbedPrivate   *embedPrivate;
++  GdkWindowAttr   attributes;
++  gint            attributes_mask;
++  
++  g_return_if_fail(widget != NULL);
++  g_return_if_fail(GTK_IS_MOZ_EMBED(widget));
++
++  embed = GTK_MOZ_EMBED(widget);
++  embedPrivate = (EmbedPrivate *)embed->data;
++
++  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 = embedPrivate->Init(embed);
++  g_return_if_fail(NS_SUCCEEDED(rv));
++  
++  PRBool alreadyRealized = PR_FALSE;
++  rv = embedPrivate->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;
++
++  if (embedPrivate->mURI.Length())
++    embedPrivate->LoadCurrentURI();
++
++  // connect to the focus out event for the child
++  GtkWidget *child_widget = GTK_BIN(widget)->child;
++  g_signal_connect_object(G_OBJECT(child_widget),
++                          "focus_out_event",
++                          G_CALLBACK(handle_child_focus_out),
++                          embed,
++                          G_CONNECT_AFTER);
++  g_signal_connect_object(G_OBJECT(child_widget),
++                          "focus_in_event",
++                          G_CALLBACK(handle_child_focus_in),
++                          embed,
++                          G_CONNECT_AFTER);
++}
++
++static void
++gtk_moz_embed_unrealize(GtkWidget *widget)
++{
++  GtkMozEmbed  *embed;
++  EmbedPrivate *embedPrivate;
++  
++  g_return_if_fail(widget != NULL);
++  g_return_if_fail(GTK_IS_MOZ_EMBED(widget));
++
++  embed = GTK_MOZ_EMBED(widget);
++  embedPrivate = (EmbedPrivate *)embed->data;
++
++  if (embedPrivate) {
++    embedPrivate->Unrealize();
++  }
++
++  if (GTK_WIDGET_CLASS(embed_parent_class)->unrealize)
++    (* GTK_WIDGET_CLASS(embed_parent_class)->unrealize)(widget);
++}
++
++static void
++gtk_moz_embed_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
++{
++  GtkMozEmbed  *embed;
++  EmbedPrivate *embedPrivate;
++  
++  g_return_if_fail(widget != NULL);
++  g_return_if_fail(GTK_IS_MOZ_EMBED(widget));
++
++  embed = GTK_MOZ_EMBED(widget);
++  embedPrivate = (EmbedPrivate *)embed->data;
++  
++  widget->allocation = *allocation;
++
++  if (GTK_WIDGET_REALIZED(widget))
++  {
++    gdk_window_move_resize(widget->window,
++			   allocation->x, allocation->y,
++			   allocation->width, allocation->height);
++    embedPrivate->Resize(allocation->width, allocation->height);
++  }
++}
++
++static void
++gtk_moz_embed_map(GtkWidget *widget)
++{
++  GtkMozEmbed  *embed;
++  EmbedPrivate *embedPrivate;
++  
++  g_return_if_fail(widget != NULL);
++  g_return_if_fail(GTK_IS_MOZ_EMBED(widget));
++
++  embed = GTK_MOZ_EMBED(widget);
++  embedPrivate = (EmbedPrivate *)embed->data;
++
++  GTK_WIDGET_SET_FLAGS(widget, GTK_MAPPED);
++
++  embedPrivate->Show();
++
++  gdk_window_show(widget->window);
++  
++}
++
++static void
++gtk_moz_embed_unmap(GtkWidget *widget)
++{
++  GtkMozEmbed  *embed;
++  EmbedPrivate *embedPrivate;
++  
++  g_return_if_fail(widget != NULL);
++  g_return_if_fail(GTK_IS_MOZ_EMBED(widget));
++
++  embed = GTK_MOZ_EMBED(widget);
++  embedPrivate = (EmbedPrivate *)embed->data;
++
++  GTK_WIDGET_UNSET_FLAGS(widget, GTK_MAPPED);
++
++  gdk_window_hide(widget->window);
++
++  embedPrivate->Hide();
++}
++
++#ifdef MOZ_ACCESSIBILITY_ATK
++static AtkObject*
++gtk_moz_embed_get_accessible (GtkWidget *widget)
++{
++  g_return_val_if_fail(widget != NULL, NULL);
++  g_return_val_if_fail(GTK_IS_MOZ_EMBED(widget), NULL);
++
++  GtkMozEmbed  *embed = GTK_MOZ_EMBED(widget);;
++  EmbedPrivate *embedPrivate = (EmbedPrivate *)embed->data;
++  return static_cast<AtkObject *>(
++                        embedPrivate->GetAtkObjectForCurrentDocument());
++}
++#endif /* MOZ_ACCESSIBILITY_ATK */
++
++static gint
++handle_child_focus_in(GtkWidget     *aWidget,
++		      GdkEventFocus *aGdkFocusEvent,
++		      GtkMozEmbed   *aEmbed)
++{
++  EmbedPrivate *embedPrivate;
++
++  embedPrivate = (EmbedPrivate *)aEmbed->data;
++
++  embedPrivate->ChildFocusIn();
++
++  return FALSE;
++}
++
++static gint
++handle_child_focus_out(GtkWidget     *aWidget,
++		       GdkEventFocus *aGdkFocusEvent,
++		       GtkMozEmbed   *aEmbed)
++{
++  EmbedPrivate *embedPrivate;
++
++  embedPrivate = (EmbedPrivate *)aEmbed->data;
++
++  embedPrivate->ChildFocusOut();
++ 
++  return FALSE;
++}
++
++// Widget methods
++
++void
++gtk_moz_embed_push_startup(void)
++{
++  EmbedPrivate::PushStartup();
++}
++
++void
++gtk_moz_embed_pop_startup(void)
++{
++  EmbedPrivate::PopStartup();
++}
++
++void
++gtk_moz_embed_set_path(const char *aPath)
++{
++  EmbedPrivate::SetPath(aPath);
++}
++
++void
++gtk_moz_embed_set_comp_path(const char *aPath)
++{
++  EmbedPrivate::SetCompPath(aPath);
++}
++
++void
++gtk_moz_embed_set_profile_path(const char *aDir, const char *aName)
++{
++  EmbedPrivate::SetProfilePath(aDir, aName);
++}
++
++void
++gtk_moz_embed_set_directory_service_provider(nsIDirectoryServiceProvider *appFileLocProvider) {
++  EmbedPrivate::SetDirectoryServiceProvider(appFileLocProvider);
++}
++
++void
++gtk_moz_embed_load_url(GtkMozEmbed *embed, const char *url)
++{
++  EmbedPrivate *embedPrivate;
++  
++  g_return_if_fail(embed != NULL);
++  g_return_if_fail(GTK_IS_MOZ_EMBED(embed));
++
++  embedPrivate = (EmbedPrivate *)embed->data;
++
++  embedPrivate->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))
++    embedPrivate->LoadCurrentURI();
++}
++
++void
++gtk_moz_embed_stop_load(GtkMozEmbed *embed)
++{
++  EmbedPrivate *embedPrivate;
++  
++  g_return_if_fail(embed != NULL);
++  g_return_if_fail(GTK_IS_MOZ_EMBED(embed));
++
++  embedPrivate = (EmbedPrivate *)embed->data;
++
++  if (embedPrivate->mNavigation)
++    embedPrivate->mNavigation->Stop(nsIWebNavigation::STOP_ALL);
++}
++
++gboolean
++gtk_moz_embed_can_go_back(GtkMozEmbed *embed)
++{
++  PRBool retval = PR_FALSE;
++  EmbedPrivate *embedPrivate;
++
++  g_return_val_if_fail ((embed != NULL), FALSE);
++  g_return_val_if_fail (GTK_IS_MOZ_EMBED(embed), FALSE);
++
++  embedPrivate = (EmbedPrivate *)embed->data;
++
++  if (embedPrivate->mNavigation)
++    embedPrivate->mNavigation->GetCanGoBack(&retval);
++  return retval;
++}
++
++gboolean
++gtk_moz_embed_can_go_forward(GtkMozEmbed *embed)
++{
++  PRBool retval = PR_FALSE;
++  EmbedPrivate *embedPrivate;
++
++  g_return_val_if_fail ((embed != NULL), FALSE);
++  g_return_val_if_fail (GTK_IS_MOZ_EMBED(embed), FALSE);
++
++  embedPrivate = (EmbedPrivate *)embed->data;
++
++  if (embedPrivate->mNavigation)
++    embedPrivate->mNavigation->GetCanGoForward(&retval);
++  return retval;
++}
++
++void
++gtk_moz_embed_go_back(GtkMozEmbed *embed)
++{
++  EmbedPrivate *embedPrivate;
++
++  g_return_if_fail (embed != NULL);
++  g_return_if_fail (GTK_IS_MOZ_EMBED(embed));
++
++  embedPrivate = (EmbedPrivate *)embed->data;
++
++  if (embedPrivate->mNavigation)
++    embedPrivate->mNavigation->GoBack();
++}
++
++void
++gtk_moz_embed_go_forward(GtkMozEmbed *embed)
++{
++  EmbedPrivate *embedPrivate;
++
++  g_return_if_fail (embed != NULL);
++  g_return_if_fail (GTK_IS_MOZ_EMBED(embed));
++
++  embedPrivate = (EmbedPrivate *)embed->data;
++
++  if (embedPrivate->mNavigation)
++    embedPrivate->mNavigation->GoForward();
++}
++
++void
++gtk_moz_embed_render_data(GtkMozEmbed *embed, const char *data,
++			  guint32 len, const char *base_uri,
++			  const char *mime_type)
++{
++  EmbedPrivate *embedPrivate;
++
++  g_return_if_fail (embed != NULL);
++  g_return_if_fail (GTK_IS_MOZ_EMBED(embed));
++
++  embedPrivate = (EmbedPrivate *)embed->data;
++
++  embedPrivate->OpenStream(base_uri, mime_type);
++  embedPrivate->AppendToStream((const PRUint8*)data, len);
++  embedPrivate->CloseStream();
++}
++
++void
++gtk_moz_embed_open_stream(GtkMozEmbed *embed, const char *base_uri,
++			  const char *mime_type)
++{
++  EmbedPrivate *embedPrivate;
++
++  g_return_if_fail (embed != NULL);
++  g_return_if_fail (GTK_IS_MOZ_EMBED(embed));
++  g_return_if_fail (GTK_WIDGET_REALIZED(GTK_WIDGET(embed)));
++
++  embedPrivate = (EmbedPrivate *)embed->data;
++
++  embedPrivate->OpenStream(base_uri, mime_type);
++}
++
++void gtk_moz_embed_append_data(GtkMozEmbed *embed, const char *data,
++			       guint32 len)
++{
++  EmbedPrivate *embedPrivate;
++
++  g_return_if_fail (embed != NULL);
++  g_return_if_fail (GTK_IS_MOZ_EMBED(embed));
++  g_return_if_fail (GTK_WIDGET_REALIZED(GTK_WIDGET(embed)));
++
++  embedPrivate = (EmbedPrivate *)embed->data;
++  embedPrivate->AppendToStream((const PRUint8*)data, len);
++}
++
++void
++gtk_moz_embed_close_stream(GtkMozEmbed *embed)
++{
++  EmbedPrivate *embedPrivate;
++
++  g_return_if_fail (embed != NULL);
++  g_return_if_fail (GTK_IS_MOZ_EMBED(embed));
++  g_return_if_fail (GTK_WIDGET_REALIZED(GTK_WIDGET(embed)));
++
++  embedPrivate = (EmbedPrivate *)embed->data;
++  embedPrivate->CloseStream();
++}
++
++char *
++gtk_moz_embed_get_link_message(GtkMozEmbed *embed)
++{
++  char *retval = nsnull;
++  EmbedPrivate *embedPrivate;
++
++  g_return_val_if_fail ((embed != NULL), (char *)NULL);
++  g_return_val_if_fail (GTK_IS_MOZ_EMBED(embed), (char *)NULL);
++
++  embedPrivate = (EmbedPrivate *)embed->data;
++
++  if (embedPrivate->mWindow)
++    retval = NEW_TOOLKIT_STRING(embedPrivate->mWindow->mLinkMessage);
++
++  return retval;
++}
++
++char *
++gtk_moz_embed_get_js_status(GtkMozEmbed *embed)
++{
++  char *retval = nsnull;
++  EmbedPrivate *embedPrivate;
++
++  g_return_val_if_fail ((embed != NULL), (char *)NULL);
++  g_return_val_if_fail (GTK_IS_MOZ_EMBED(embed), (char *)NULL);
++
++  embedPrivate = (EmbedPrivate *)embed->data;
++
++  if (embedPrivate->mWindow)
++    retval = NEW_TOOLKIT_STRING(embedPrivate->mWindow->mJSStatus);
++
++  return retval;
++}
++
++char *
++gtk_moz_embed_get_title(GtkMozEmbed *embed)
++{
++  char *retval = nsnull;
++  EmbedPrivate *embedPrivate;
++
++  g_return_val_if_fail ((embed != NULL), (char *)NULL);
++  g_return_val_if_fail (GTK_IS_MOZ_EMBED(embed), (char *)NULL);
++
++  embedPrivate = (EmbedPrivate *)embed->data;
++
++  if (embedPrivate->mWindow)
++    retval = NEW_TOOLKIT_STRING(embedPrivate->mWindow->mTitle);
++
++  return retval;
++}
++
++char *
++gtk_moz_embed_get_location(GtkMozEmbed *embed)
++{
++  char *retval = nsnull;
++  EmbedPrivate *embedPrivate;
++
++  g_return_val_if_fail ((embed != NULL), (char *)NULL);
++  g_return_val_if_fail (GTK_IS_MOZ_EMBED(embed), (char *)NULL);
++
++  embedPrivate = (EmbedPrivate *)embed->data;
++  
++  if (!embedPrivate->mURI.IsEmpty())
++    retval = g_strdup(embedPrivate->mURI.get());
++
++  return retval;
++}
++
++void
++gtk_moz_embed_reload(GtkMozEmbed *embed, gint32 flags)
++{
++  EmbedPrivate *embedPrivate;
++
++  g_return_if_fail (embed != NULL);
++  g_return_if_fail (GTK_IS_MOZ_EMBED(embed));
++
++  embedPrivate = (EmbedPrivate *)embed->data;
++
++  PRUint32 reloadFlags = 0;
++  
++  // map the external API to the internal web navigation API.
++  switch (flags) {
++  case GTK_MOZ_EMBED_FLAG_RELOADNORMAL:
++    reloadFlags = 0;
++    break;
++  case GTK_MOZ_EMBED_FLAG_RELOADBYPASSCACHE:
++    reloadFlags = nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE;
++    break;
++  case GTK_MOZ_EMBED_FLAG_RELOADBYPASSPROXY:
++    reloadFlags = nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY;
++    break;
++  case GTK_MOZ_EMBED_FLAG_RELOADBYPASSPROXYANDCACHE:
++    reloadFlags = (nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY |
++		   nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE);
++    break;
++  case GTK_MOZ_EMBED_FLAG_RELOADCHARSETCHANGE:
++    reloadFlags = nsIWebNavigation::LOAD_FLAGS_CHARSET_CHANGE;
++    break;
++  default:
++    reloadFlags = 0;
++    break;
++  }
++
++  embedPrivate->Reload(reloadFlags);
++}
++
++void
++gtk_moz_embed_set_chrome_mask(GtkMozEmbed *embed, guint32 flags)
++{
++  EmbedPrivate *embedPrivate;
++
++  g_return_if_fail (embed != NULL);
++  g_return_if_fail (GTK_IS_MOZ_EMBED(embed));
++
++  embedPrivate = (EmbedPrivate *)embed->data;
++
++  embedPrivate->SetChromeMask(flags);
++}
++
++guint32
++gtk_moz_embed_get_chrome_mask(GtkMozEmbed *embed)
++{
++  EmbedPrivate *embedPrivate;
++
++  g_return_val_if_fail ((embed != NULL), 0);
++  g_return_val_if_fail (GTK_IS_MOZ_EMBED(embed), 0);
++
++  embedPrivate = (EmbedPrivate *)embed->data;
++
++  return embedPrivate->mChromeMask;
++}
++
++void
++gtk_moz_embed_get_nsIWebBrowser  (GtkMozEmbed *embed, nsIWebBrowser **retval)
++{
++  EmbedPrivate *embedPrivate;
++
++  g_return_if_fail (embed != NULL);
++  g_return_if_fail (GTK_IS_MOZ_EMBED(embed));
++
++  embedPrivate = (EmbedPrivate *)embed->data;
++  
++  if (embedPrivate->mWindow)
++    embedPrivate->mWindow->GetWebBrowser(retval);
++}
++
++PRUnichar *
++gtk_moz_embed_get_title_unichar (GtkMozEmbed *embed)
++{
++  PRUnichar *retval = nsnull;
++  EmbedPrivate *embedPrivate;
++                   
++  g_return_val_if_fail ((embed != NULL), (PRUnichar *)NULL);
++  g_return_val_if_fail (GTK_IS_MOZ_EMBED(embed), (PRUnichar *)NULL);
++  
++  embedPrivate = (EmbedPrivate *)embed->data;
++                   
++  if (embedPrivate->mWindow)
++    retval = ToNewUnicode(embedPrivate->mWindow->mTitle);
++                   
++  return retval;
++}
++
++PRUnichar *
++gtk_moz_embed_get_js_status_unichar (GtkMozEmbed *embed)
++{
++  PRUnichar *retval = nsnull;
++  EmbedPrivate *embedPrivate;
++                   
++  g_return_val_if_fail ((embed != NULL), (PRUnichar *)NULL);
++  g_return_val_if_fail (GTK_IS_MOZ_EMBED(embed), (PRUnichar *)NULL);
++  
++  embedPrivate = (EmbedPrivate *)embed->data;
++                   
++  if (embedPrivate->mWindow)
++    retval = ToNewUnicode(embedPrivate->mWindow->mJSStatus);
++                   
++  return retval;
++}
++
++PRUnichar *
++gtk_moz_embed_get_link_message_unichar (GtkMozEmbed *embed)
++{
++  PRUnichar *retval = nsnull;
++  EmbedPrivate *embedPrivate;
++                   
++  g_return_val_if_fail ((embed != NULL), (PRUnichar *)NULL);
++  g_return_val_if_fail (GTK_IS_MOZ_EMBED(embed), (PRUnichar *)NULL);
++  
++  embedPrivate = (EmbedPrivate *)embed->data;
++                   
++  if (embedPrivate->mWindow)
++    retval = ToNewUnicode(embedPrivate->mWindow->mLinkMessage);
++                   
++  return retval;
++}
++
++// class and instance initialization
++
++static void
++gtk_moz_embed_single_class_init(GtkMozEmbedSingleClass *klass);
++
++static void
++gtk_moz_embed_single_init(GtkMozEmbedSingle *embed);
++
++GtkMozEmbedSingle *
++gtk_moz_embed_single_new(void);
++
++enum {
++  NEW_WINDOW_ORPHAN,
++  SINGLE_LAST_SIGNAL
++};
++
++guint moz_embed_single_signals[SINGLE_LAST_SIGNAL] = { 0 };
++
++// GtkObject + class-related functions
++
++GType
++gtk_moz_embed_single_get_type(void)
++{
++  static GType moz_embed_single_type = 0;
++  if (moz_embed_single_type == 0)
++  {
++    const GTypeInfo our_info =
++    {
++      sizeof(GtkMozEmbedClass),
++      NULL, /* base_init */
++      NULL, /* base_finalize */
++      (GClassInitFunc)gtk_moz_embed_single_class_init,
++      NULL,
++      NULL, /* class_data */
++      sizeof(GtkMozEmbed),
++      0, /* n_preallocs */
++      (GInstanceInitFunc)gtk_moz_embed_single_init,
++    };
++
++    moz_embed_single_type = g_type_register_static(GTK_TYPE_OBJECT,
++                                                   "GtkMozEmbedSingle",
++                                                   &our_info,
++                                                   (GTypeFlags)0);
++  }
++
++  return moz_embed_single_type;
++}
++
++static void
++gtk_moz_embed_single_class_init(GtkMozEmbedSingleClass *klass)
++{
++  GtkObjectClass     *object_class;
++
++  object_class    = GTK_OBJECT_CLASS(klass);
++
++  // set up our signals
++
++  moz_embed_single_signals[NEW_WINDOW_ORPHAN] =
++    g_signal_new("new_window_orphan",
++                 G_TYPE_FROM_CLASS(klass),
++                 G_SIGNAL_RUN_FIRST,
++                 G_STRUCT_OFFSET(GtkMozEmbedSingleClass, new_window_orphan),
++                 NULL, NULL,
++                 gtkmozembed_VOID__POINTER_UINT,
++                 G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_UINT);
++
++}
++
++static void
++gtk_moz_embed_single_init(GtkMozEmbedSingle *embed)
++{
++  // this is a placeholder for later in case we need to stash data at
++  // a later data and maintain backwards compatibility.
++  embed->data = nsnull;
++}
++
++GtkMozEmbedSingle *
++gtk_moz_embed_single_new(void)
++{
++  return (GtkMozEmbedSingle *)g_object_new(GTK_TYPE_MOZ_EMBED_SINGLE, NULL);
++}
++
++GtkMozEmbedSingle *
++gtk_moz_embed_single_get(void)
++{
++  static GtkMozEmbedSingle *singleton_object = nsnull;
++  if (!singleton_object)
++  {
++    singleton_object = gtk_moz_embed_single_new();
++  }
++
++  return singleton_object;
++}
++
++// our callback from the window creator service
++void
++gtk_moz_embed_single_create_window(GtkMozEmbed **aNewEmbed,
++				   guint         aChromeFlags)
++{
++  GtkMozEmbedSingle *single = gtk_moz_embed_single_get();
++
++  *aNewEmbed = nsnull;
++
++  if (!single)
++    return;
++
++  g_signal_emit(G_OBJECT(single),
++                moz_embed_single_signals[NEW_WINDOW_ORPHAN], 0,
++                aNewEmbed, aChromeFlags);
++
++}
+diff --git a/embedding/browser/gtk/src/gtkmozembed_glue.cpp b/embedding/browser/gtk/src/gtkmozembed_glue.cpp
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/src/gtkmozembed_glue.cpp
+@@ -0,0 +1,116 @@
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is Mozilla embedding.
++ *
++ * The Initial Developer of the Original Code is
++ * Benjamin Smedberg <[email protected]>.
++ *
++ * Portions created by the Initial Developer are Copyright (C) 2005
++ * the Mozilla Foundation <http://www.mozilla.org/>. All Rights Reserved.
++ *
++ * Contributor(s):
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++// This file is an implementation file, meant to be #included in a
++// single C++ file of an embedding application. It is called after
++// XPCOMGlueStartup to glue the gtkmozembed functions.
++
++#include "gtkmozembed.h"
++#include "gtkmozembed_internal.h"
++#include "nsXPCOMGlue.h"
++
++#ifndef XPCOM_GLUE
++#error This file only makes sense when XPCOM_GLUE is defined.
++#endif
++
++#define GTKMOZEMBED_FUNCTIONS \
++  GTKF(gtk_moz_embed_get_type) \
++  GTKF(gtk_moz_embed_new) \
++  GTKF(gtk_moz_embed_push_startup) \
++  GTKF(gtk_moz_embed_pop_startup) \
++  GTKF(gtk_moz_embed_set_path) \
++  GTKF(gtk_moz_embed_set_comp_path) \
++  GTKF(gtk_moz_embed_set_profile_path) \
++  GTKF(gtk_moz_embed_load_url) \
++  GTKF(gtk_moz_embed_stop_load) \
++  GTKF(gtk_moz_embed_can_go_back) \
++  GTKF(gtk_moz_embed_can_go_forward) \
++  GTKF(gtk_moz_embed_go_back) \
++  GTKF(gtk_moz_embed_go_forward) \
++  GTKF(gtk_moz_embed_render_data) \
++  GTKF(gtk_moz_embed_open_stream) \
++  GTKF(gtk_moz_embed_append_data) \
++  GTKF(gtk_moz_embed_close_stream) \
++  GTKF(gtk_moz_embed_get_link_message) \
++  GTKF(gtk_moz_embed_get_js_status) \
++  GTKF(gtk_moz_embed_get_title) \
++  GTKF(gtk_moz_embed_get_location) \
++  GTKF(gtk_moz_embed_reload) \
++  GTKF(gtk_moz_embed_set_chrome_mask) \
++  GTKF(gtk_moz_embed_get_chrome_mask) \
++  GTKF(gtk_moz_embed_single_get_type) \
++  GTKF(gtk_moz_embed_single_get)
++
++#define GTKMOZEMBED_FUNCTIONS_INTERNAL \
++  GTKF(gtk_moz_embed_get_nsIWebBrowser) \
++  GTKF(gtk_moz_embed_get_title_unichar) \
++  GTKF(gtk_moz_embed_get_js_status_unichar) \
++  GTKF(gtk_moz_embed_get_link_message_unichar) \
++  GTKF(gtk_moz_embed_set_directory_service_provider)
++
++#define GTKF(fname) fname##Type fname;
++
++GTKMOZEMBED_FUNCTIONS
++GTKMOZEMBED_FUNCTIONS_INTERNAL
++
++#undef GTKF
++
++#define GTKF(fname) { #fname, (NSFuncPtr*) &fname },
++
++static const nsDynamicFunctionLoad GtkSymbols[] = {
++GTKMOZEMBED_FUNCTIONS
++  { nsnull, nsnull }
++};
++
++static const nsDynamicFunctionLoad GtkSymbolsInternal[] = {
++GTKMOZEMBED_FUNCTIONS_INTERNAL
++  { nsnull, nsnull }
++};
++#undef GTKF
++
++static nsresult
++GTKEmbedGlueStartup()
++{
++  return XPCOMGlueLoadXULFunctions(GtkSymbols);
++}
++
++static nsresult
++GTKEmbedGlueStartupInternal()
++{
++  return XPCOMGlueLoadXULFunctions(GtkSymbolsInternal);
++}
++
+diff --git a/embedding/browser/gtk/src/gtkmozembed_internal.h b/embedding/browser/gtk/src/gtkmozembed_internal.h
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/src/gtkmozembed_internal.h
+@@ -0,0 +1,70 @@
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * Christopher Blizzard.
++ * Portions created by the Initial Developer are Copyright (C) 2001
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *   Christopher Blizzard <[email protected]>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#ifndef gtkmozembed_internal_h
++#define gtkmozembed_internal_h
++
++#include "nsIWebBrowser.h"
++#include "nsXPCOM.h"
++
++struct nsModuleComponentInfo;
++
++#ifdef __cplusplus
++extern "C" {
++#endif /* __cplusplus */
++
++GTKMOZEMBED_API(void,
++  gtk_moz_embed_get_nsIWebBrowser, (GtkMozEmbed *embed,
++                                    nsIWebBrowser **retval))
++GTKMOZEMBED_API(PRUnichar*,
++  gtk_moz_embed_get_title_unichar, (GtkMozEmbed *embed))
++
++GTKMOZEMBED_API(PRUnichar*,
++  gtk_moz_embed_get_js_status_unichar, (GtkMozEmbed *embed))
++
++GTKMOZEMBED_API(PRUnichar*,
++  gtk_moz_embed_get_link_message_unichar, (GtkMozEmbed *embed))
++
++GTKMOZEMBED_API(void,
++  gtk_moz_embed_set_directory_service_provider, (nsIDirectoryServiceProvider *appFileLocProvider))
++
++#ifdef __cplusplus
++}
++#endif /* __cplusplus */
++
++#endif /* gtkmozembed_internal_h */
++
+diff --git a/embedding/browser/gtk/src/gtkmozembedmarshal.list b/embedding/browser/gtk/src/gtkmozembedmarshal.list
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/src/gtkmozembedmarshal.list
+@@ -0,0 +1,34 @@
++BOOL:STRING
++BOOL:STRING,STRING
++BOOL:STRING,STRING,POINTER
++BOOL:STRING,STRING,POINTER,INT
++BOOL:STRING,STRING,POINTER,POINTER,STRING,POINTER
++BOOL:STRING,STRING,POINTER,STRING,POINTER
++BOOL:STRING,STRING,STRING,POINTER
++INT:STRING,INT,INT,INT,INT,INT
++INT:STRING,STRING,INT,INT,INT,INT
++INT:STRING,STRING,UINT,STRING,STRING,STRING,STRING,POINTER
++INT:VOID
++STRING:STRING,STRING
++VOID:BOOL
++VOID:INT,INT
++VOID:INT,INT,BOOL
++VOID:INT,STRING
++VOID:INT,STRING,STRING
++VOID:INT,UINT
++VOID:POINTER,INT,POINTER
++VOID:POINTER,INT,STRING,STRING,STRING,STRING,STRING,BOOLEAN,INT
++VOID:POINTER,STRING,BOOL,BOOL
++VOID:STRING,INT,INT
++VOID:STRING,INT,UINT
++VOID:STRING,STRING
++VOID:STRING,STRING,POINTER
++VOID:STRING,STRING,STRING,ULONG,INT
++VOID:STRING,STRING,STRING,POINTER
++VOID:UINT,INT,INT,STRING,STRING,STRING,STRING
++VOID:ULONG,ULONG,ULONG
++VOID:POINTER,UINT
++BOOL:POINTER,UINT
++BOOL:POINTER
++VOID:POINTER
++BOOL:STRING,STRING,POINTER
+diff --git a/embedding/browser/gtk/src/gtkmozembedprivate.h b/embedding/browser/gtk/src/gtkmozembedprivate.h
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/src/gtkmozembedprivate.h
+@@ -0,0 +1,91 @@
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * Christopher Blizzard.
++ * Portions created by the Initial Developer are Copyright (C) 2001
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *   Christopher Blizzard <[email protected]>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#ifndef gtkmozembedprivate_h
++#define gtkmozembedprivate_h
++
++#ifdef __cplusplus
++extern "C" {
++#endif /* __cplusplus */
++
++#include "gtkmozembed.h"
++
++/* signals */
++
++enum {
++  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,
++  DOM_KEY_DOWN,
++  DOM_KEY_PRESS,
++  DOM_KEY_UP,
++  DOM_MOUSE_DOWN,
++  DOM_MOUSE_UP,
++  DOM_MOUSE_CLICK,
++  DOM_MOUSE_DBL_CLICK,
++  DOM_MOUSE_OVER,
++  DOM_MOUSE_OUT,
++  SECURITY_CHANGE,
++  STATUS_CHANGE,
++  DOM_ACTIVATE,
++  DOM_FOCUS_IN,
++  DOM_FOCUS_OUT,
++  EMBED_LAST_SIGNAL
++};
++
++extern guint moz_embed_signals[EMBED_LAST_SIGNAL];
++
++extern void gtk_moz_embed_single_create_window(GtkMozEmbed **aNewEmbed,
++					       guint aChromeFlags);
++
++#ifdef __cplusplus
++}
++#endif /* __cplusplus */
++
++#endif /* gtkmozembedprivate_h */
+diff --git a/embedding/browser/gtk/tests/Makefile.in b/embedding/browser/gtk/tests/Makefile.in
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/tests/Makefile.in
+@@ -0,0 +1,101 @@
++# 
++# ***** BEGIN LICENSE BLOCK *****
++# Version: MPL 1.1/GPL 2.0/LGPL 2.1
++#
++# The contents of this file are subject to the Mozilla Public License Version
++# 1.1 (the "License"); you may not use this file except in compliance with
++# the License. You may obtain a copy of the License at
++# http://www.mozilla.org/MPL/
++#
++# Software distributed under the License is distributed on an "AS IS" basis,
++# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++# for the specific language governing rights and limitations under the
++# License.
++#
++# The Original Code is the Mozilla browser.
++#
++# The Initial Developer of the Original Code is
++# Christopher Blizzard.
++# Portions created by the Initial Developer are Copyright (C) 1999
++# the Initial Developer. All Rights Reserved.
++#
++# Contributor(s):
++#   Christopher Blizzard <[email protected]>
++#
++# Alternatively, the contents of this file may be used under the terms of
++# either the GNU General Public License Version 2 or later (the "GPL"), or
++# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++# in which case the provisions of the GPL or the LGPL are applicable instead
++# of those above. If you wish to allow use of your version of this file only
++# under the terms of either the GPL or the LGPL, and not to allow others to
++# use your version of this file under the terms of the MPL, indicate your
++# decision by deleting the provisions above and replace them with the notice
++# and other provisions required by the GPL or the LGPL. If you do not delete
++# the provisions above, a recipient may use your version of this file under
++# the terms of any one of the MPL, the GPL or the LGPL.
++#
++# ***** END LICENSE BLOCK *****
++
++DEPTH		= ../../../..
++topsrcdir	= @top_srcdir@
++srcdir		= @srcdir@
++VPATH		= @srcdir@
++
++include $(DEPTH)/config/autoconf.mk
++
++MODULE		= gtkembedmoz
++
++CPPSRCS         = \
++		TestGtkEmbed.cpp \
++		TestGtkEmbedNotebook.cpp
++
++ifdef MOZ_X11
++CPPSRCS +=	TestGtkEmbedSocket.cpp \
++		TestGtkEmbedChild.cpp
++endif
++
++SIMPLE_PROGRAMS = $(CPPSRCS:.cpp=)
++
++# ENABLE_GNOME=1
++
++ifdef ENABLE_GNOME
++CPPSRCS	       += TestGtkEmbedMDI.cpp
++endif
++
++ifdef MOZ_ENABLE_GTK2
++LIBS		+= \
++		$(XLDFLAGS) \
++		$(XLIBS) \
++		$(NULL)
++endif
++
++include $(topsrcdir)/config/config.mk
++
++include $(topsrcdir)/config/rules.mk
++
++LIBS += $(XPCOM_STANDALONE_GLUE_LDOPTS)
++
++DEFINES += -DXPCOM_GLUE
++STL_FLAGS =
++
++CXXFLAGS	+= $(MOZ_GTK2_CFLAGS)
++
++ifdef ENABLE_GNOME
++CXXFLAGS	+= `gnome-config --cflags gnomeui`
++EXTRA_LIBS	+= `gnome-config --libs gnomeui`
++endif
++
++EXTRA_LIBS	+= \
++		$(TK_LIBS) \
++		$(NULL)
++
++ifeq ($(OS_ARCH), SunOS)
++ifndef GNU_CC
++# When using Sun's WorkShop compiler, including
++# /wherever/workshop-5.0/SC5.0/include/CC/std/time.h
++# causes most of these compiles to fail with:
++# line 29: Error: Multiple declaration for std::tm.
++# So, this gets around the problem.
++DEFINES           += -D_TIME_H=1
++endif
++endif
+diff --git a/embedding/browser/gtk/tests/TestGtkEmbed.cpp b/embedding/browser/gtk/tests/TestGtkEmbed.cpp
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/tests/TestGtkEmbed.cpp
+@@ -0,0 +1,1145 @@
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * Christopher Blizzard.
++ * Portions created by the Initial Developer are Copyright (C) 2001
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *   Christopher Blizzard <[email protected]>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#include "gtkmozembed.h"
++#include <gtk/gtk.h>
++#include <stdio.h>
++#include <string.h>
++#include <stdlib.h>
++
++// mozilla specific headers
++#include "nsIDOMKeyEvent.h"
++#include "nsIDOMMouseEvent.h"
++#include "nsIDOMUIEvent.h"
++
++#include "nsCOMPtr.h"
++#include "nsISupportsUtils.h"
++#include "nsServiceManagerUtils.h"
++#include "nsIObserverService.h"
++
++#include "nsStringAPI.h"
++#include "gtkmozembed_glue.cpp"
++
++typedef struct _TestGtkBrowser {
++  GtkWidget  *topLevelWindow;
++  GtkWidget  *topLevelVBox;
++  GtkWidget  *menuBar;
++  GtkWidget  *fileMenuItem;
++  GtkWidget  *fileMenu;
++  GtkWidget  *fileOpenNewBrowser;
++  GtkWidget  *fileStream;
++  GtkWidget  *fileMemory;
++  GtkWidget  *fileClose;
++  GtkWidget  *fileQuit;
++  GtkWidget  *toolbarHBox;
++  GtkWidget  *toolbar;
++  GtkWidget  *backButton;
++  GtkWidget  *stopButton;
++  GtkWidget  *forwardButton;
++  GtkWidget  *reloadButton;
++  GtkWidget  *urlEntry;
++  GtkWidget  *mozEmbed;
++  GtkWidget  *progressAreaHBox;
++  GtkWidget  *progressBar;
++  GtkWidget  *statusAlign;
++  GtkWidget  *statusBar;
++  const char *statusMessage;
++  int         loadPercent;
++  int         bytesLoaded;
++  int         maxBytesLoaded;
++  char       *tempMessage;
++  gboolean menuBarOn;
++  gboolean toolBarOn;
++  gboolean locationBarOn;
++  gboolean statusBarOn;
++
++} TestGtkBrowser;
++
++// the list of browser windows currently open
++GList *browser_list = g_list_alloc();
++
++static TestGtkBrowser *new_gtk_browser    (guint32 chromeMask);
++static void            set_browser_visibility (TestGtkBrowser *browser,
++					       gboolean visibility);
++
++static int num_browsers = 0;
++
++// callbacks from the UI
++static void     back_clicked_cb    (GtkButton   *button, 
++				    TestGtkBrowser *browser);
++static void     stop_clicked_cb    (GtkButton   *button,
++				    TestGtkBrowser *browser);
++static void     forward_clicked_cb (GtkButton   *button,
++				    TestGtkBrowser *browser);
++static void     reload_clicked_cb  (GtkButton   *button,
++				    TestGtkBrowser *browser);
++static void     url_activate_cb    (GtkEditable *widget, 
++				    TestGtkBrowser *browser);
++static void     menu_open_new_cb   (GtkMenuItem *menuitem,
++				    TestGtkBrowser *browser);
++static void     menu_stream_cb     (GtkMenuItem *menuitem,
++				    TestGtkBrowser *browser);
++static void     menu_memory_cb     (GtkMenuItem *menuitem,
++				    TestGtkBrowser *browser);
++static void     menu_close_cb      (GtkMenuItem *menuitem,
++				    TestGtkBrowser *browser);
++static void     menu_quit_cb       (GtkMenuItem *menuitem,
++				    TestGtkBrowser *browser);
++static gboolean delete_cb          (GtkWidget *widget, GdkEventAny *event,
++				    TestGtkBrowser *browser);
++static void     destroy_cb         (GtkWidget *widget,
++				    TestGtkBrowser *browser);
++
++// callbacks from the widget
++static void location_changed_cb  (GtkMozEmbed *embed, TestGtkBrowser *browser);
++static void title_changed_cb     (GtkMozEmbed *embed, TestGtkBrowser *browser);
++static void load_started_cb      (GtkMozEmbed *embed, TestGtkBrowser *browser);
++static void load_finished_cb     (GtkMozEmbed *embed, TestGtkBrowser *browser);
++static void net_state_change_cb  (GtkMozEmbed *embed, gint flags,
++				  guint status, TestGtkBrowser *browser);
++static void net_state_change_all_cb (GtkMozEmbed *embed, const char *uri,
++				     gint flags, guint status,
++				     TestGtkBrowser *browser);
++static void progress_change_cb   (GtkMozEmbed *embed, gint cur, gint max,
++				  TestGtkBrowser *browser);
++static void progress_change_all_cb (GtkMozEmbed *embed, const char *uri,
++				    gint cur, gint max,
++				    TestGtkBrowser *browser);
++static void link_message_cb      (GtkMozEmbed *embed, TestGtkBrowser *browser);
++static void js_status_cb         (GtkMozEmbed *embed, TestGtkBrowser *browser);
++static void new_window_cb        (GtkMozEmbed *embed,
++				  GtkMozEmbed **retval, guint chromemask,
++				  TestGtkBrowser *browser);
++static void visibility_cb        (GtkMozEmbed *embed, 
++				  gboolean visibility,
++				  TestGtkBrowser *browser);
++static void destroy_brsr_cb      (GtkMozEmbed *embed, TestGtkBrowser *browser);
++static gint open_uri_cb          (GtkMozEmbed *embed, const char *uri,
++				  TestGtkBrowser *browser);
++static void size_to_cb           (GtkMozEmbed *embed, gint width,
++				  gint height, TestGtkBrowser *browser);
++static gint dom_key_down_cb      (GtkMozEmbed *embed, nsIDOMKeyEvent *event,
++				  TestGtkBrowser *browser);
++static gint dom_key_press_cb     (GtkMozEmbed *embed, nsIDOMKeyEvent *event,
++				  TestGtkBrowser *browser);
++static gint dom_key_up_cb        (GtkMozEmbed *embed, nsIDOMKeyEvent *event,
++				  TestGtkBrowser *browser);
++static gint dom_mouse_down_cb    (GtkMozEmbed *embed, nsIDOMMouseEvent *event,
++				  TestGtkBrowser *browser);
++static gint dom_mouse_up_cb      (GtkMozEmbed *embed, nsIDOMMouseEvent *event,
++				  TestGtkBrowser *browser);
++static gint dom_mouse_click_cb   (GtkMozEmbed *embed, nsIDOMMouseEvent *event,
++				  TestGtkBrowser *browser);
++static gint dom_mouse_dbl_click_cb (GtkMozEmbed *embed, 
++				  nsIDOMMouseEvent *event,
++				  TestGtkBrowser *browser);
++static gint dom_mouse_over_cb    (GtkMozEmbed *embed, nsIDOMMouseEvent *event,
++				  TestGtkBrowser *browser);
++static gint dom_mouse_out_cb     (GtkMozEmbed *embed, nsIDOMMouseEvent *event,
++				  TestGtkBrowser *browser);
++static gint dom_activate_cb      (GtkMozEmbed *embed, nsIDOMUIEvent *event,
++				  TestGtkBrowser *browser);
++static gint dom_focus_in_cb      (GtkMozEmbed *embed, nsIDOMUIEvent *event,
++				  TestGtkBrowser *browser);
++static gint dom_focus_out_cb     (GtkMozEmbed *embed, nsIDOMUIEvent *event,
++				  TestGtkBrowser *browser);
++
++// callbacks from the singleton object
++static void new_window_orphan_cb (GtkMozEmbedSingle *embed,
++				  GtkMozEmbed **retval, guint chromemask,
++				  gpointer data);
++
++// some utility functions
++static void update_status_bar_text  (TestGtkBrowser *browser);
++static void update_temp_message     (TestGtkBrowser *browser,
++				     const char *message);
++static void update_nav_buttons      (TestGtkBrowser *browser);
++
++int
++main(int argc, char **argv)
++{
++  gtk_set_locale();
++  gtk_init(&argc, &argv);
++
++  static const GREVersionRange greVersion = {
++    "1.9a", PR_TRUE,
++    "2", PR_TRUE
++  };
++
++  char xpcomPath[PATH_MAX];
++
++  nsresult rv = GRE_GetGREPathWithProperties(&greVersion, 1, nsnull, 0,
++                                             xpcomPath, sizeof(xpcomPath));
++  if (NS_FAILED(rv)) {
++    fprintf(stderr, "Couldn't find a compatible GRE.\n");
++    return 1;
++  }
++
++  rv = XPCOMGlueStartup(xpcomPath);
++  if (NS_FAILED(rv)) {
++    fprintf(stderr, "Couldn't start XPCOM.");
++    return 1;
++  }
++
++  rv = GTKEmbedGlueStartup();
++  if (NS_FAILED(rv)) {
++    fprintf(stderr, "Couldn't find GTKMozEmbed symbols.");
++    return 1;
++  }
++
++  char *lastSlash = strrchr(xpcomPath, '/');
++  if (lastSlash)
++    *lastSlash = '\0';
++
++  gtk_moz_embed_set_path(xpcomPath);
++
++  char *home_path;
++  char *full_path;
++  home_path = getenv("HOME");
++  if (!home_path) {
++    fprintf(stderr, "Failed to get HOME\n");
++    exit(1);
++  }
++  
++  full_path = g_strdup_printf("%s/%s", home_path, ".TestGtkEmbed");
++  
++  gtk_moz_embed_set_profile_path(full_path, "TestGtkEmbed");
++
++  TestGtkBrowser *browser = new_gtk_browser(GTK_MOZ_EMBED_FLAG_DEFAULTCHROME);
++
++  // set our minimum size
++  gtk_widget_set_size_request(browser->mozEmbed, 400, 400);
++
++  set_browser_visibility(browser, TRUE);
++
++  if (argc > 1)
++    gtk_moz_embed_load_url(GTK_MOZ_EMBED(browser->mozEmbed), argv[1]);
++
++  // get the singleton object and hook up to its new window callback
++  // so we can create orphaned windows.
++
++  GtkMozEmbedSingle *single;
++
++  single = gtk_moz_embed_single_get();
++  if (!single) {
++    fprintf(stderr, "Failed to get singleton embed object!\n");
++    exit(1);
++  }
++
++  g_signal_connect(GTK_OBJECT(single), "new_window_orphan",
++                   G_CALLBACK(new_window_orphan_cb), NULL);
++
++  gtk_moz_embed_push_startup();
++  gtk_main();
++  gtk_moz_embed_pop_startup();
++}
++
++static TestGtkBrowser *
++new_gtk_browser(guint32 chromeMask)
++{
++  guint32         actualChromeMask = chromeMask;
++  TestGtkBrowser *browser = 0;
++
++  num_browsers++;
++
++  browser = g_new0(TestGtkBrowser, 1);
++
++  browser_list = g_list_prepend(browser_list, browser);
++
++  browser->menuBarOn = FALSE;
++  browser->toolBarOn = FALSE;
++  browser->locationBarOn = FALSE;
++  browser->statusBarOn = FALSE;
++
++  g_print("new_gtk_browser\n");
++
++  if (chromeMask == GTK_MOZ_EMBED_FLAG_DEFAULTCHROME)
++    actualChromeMask = GTK_MOZ_EMBED_FLAG_ALLCHROME;
++
++  if (actualChromeMask & GTK_MOZ_EMBED_FLAG_MENUBARON)
++  {
++    browser->menuBarOn = TRUE;
++    g_print("\tmenu bar\n");
++  }
++  if (actualChromeMask & GTK_MOZ_EMBED_FLAG_TOOLBARON)
++  {
++    browser->toolBarOn = TRUE;
++    g_print("\ttool bar\n");
++  }
++  if (actualChromeMask & GTK_MOZ_EMBED_FLAG_LOCATIONBARON)
++  {
++    browser->locationBarOn = TRUE;
++    g_print("\tlocation bar\n");
++  }
++  if (actualChromeMask & GTK_MOZ_EMBED_FLAG_STATUSBARON)
++  {
++    browser->statusBarOn = TRUE;
++    g_print("\tstatus bar\n");
++  }
++
++  // create our new toplevel window
++  browser->topLevelWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
++  // new vbox
++  browser->topLevelVBox = gtk_vbox_new(FALSE, 0);
++  // add it to the toplevel window
++  gtk_container_add(GTK_CONTAINER(browser->topLevelWindow),
++		    browser->topLevelVBox);
++  // create our menu bar
++  browser->menuBar = gtk_menu_bar_new();
++  // create the file menu
++  browser->fileMenuItem = gtk_menu_item_new_with_label("File");
++  browser->fileMenu = gtk_menu_new();
++  gtk_menu_item_set_submenu (GTK_MENU_ITEM(browser->fileMenuItem),
++			     browser->fileMenu);
++
++  browser->fileOpenNewBrowser = 
++    gtk_menu_item_new_with_label("Open New Browser");
++  gtk_menu_shell_append((GtkMenuShell *)GTK_MENU(browser->fileMenu),
++                        browser->fileOpenNewBrowser);
++  
++  browser->fileStream =
++    gtk_menu_item_new_with_label("Test Stream");
++  gtk_menu_shell_append((GtkMenuShell *)GTK_MENU(browser->fileMenu),
++                        browser->fileStream);
++
++  browser->fileMemory =
++    gtk_menu_item_new_with_label("Release Memory");
++  gtk_menu_shell_append((GtkMenuShell *)GTK_MENU(browser->fileMenu),
++                        browser->fileMemory);
++
++  browser->fileClose =
++    gtk_menu_item_new_with_label("Close");
++  gtk_menu_shell_append((GtkMenuShell *)GTK_MENU(browser->fileMenu),
++                        browser->fileClose);
++
++  browser->fileQuit =
++    gtk_menu_item_new_with_label("Quit");
++  gtk_menu_shell_append((GtkMenuShell *)GTK_MENU(browser->fileMenu),
++                        browser->fileQuit);
++  
++  // append it
++  gtk_menu_shell_append((GtkMenuShell *)GTK_MENU_BAR(browser->menuBar),
++                        browser->fileMenuItem);
++
++  // add it to the vbox
++  gtk_box_pack_start(GTK_BOX(browser->topLevelVBox),
++		     browser->menuBar,
++		     FALSE, // expand
++		     FALSE, // fill
++		     0);    // padding
++  // create the hbox that will contain the toolbar and the url text entry bar
++  browser->toolbarHBox = gtk_hbox_new(FALSE, 0);
++  // add that hbox to the vbox
++  gtk_box_pack_start(GTK_BOX(browser->topLevelVBox), 
++		     browser->toolbarHBox,
++		     FALSE, // expand
++		     FALSE, // fill
++		     0);    // padding
++  // new horiz toolbar with buttons + icons
++  browser->toolbar = gtk_toolbar_new();
++  gtk_toolbar_set_orientation(GTK_TOOLBAR(browser->toolbar),
++			      GTK_ORIENTATION_HORIZONTAL);
++  gtk_toolbar_set_style(GTK_TOOLBAR(browser->toolbar),
++			GTK_TOOLBAR_BOTH);
++
++  // add it to the hbox
++  gtk_box_pack_start(GTK_BOX(browser->toolbarHBox), browser->toolbar,
++		   FALSE, // expand
++		   FALSE, // fill
++		   0);    // padding
++  // new back button
++  browser->backButton =
++    gtk_toolbar_append_item(GTK_TOOLBAR(browser->toolbar),
++			    "Back",
++			    "Go Back",
++			    "Go Back",
++			    0, // XXX replace with icon
++			    G_CALLBACK(back_clicked_cb),
++			    browser);
++  // new stop button
++  browser->stopButton = 
++    gtk_toolbar_append_item(GTK_TOOLBAR(browser->toolbar),
++			    "Stop",
++			    "Stop",
++			    "Stop",
++			    0, // XXX replace with icon
++			    G_CALLBACK(stop_clicked_cb),
++			    browser);
++  // new forward button
++  browser->forwardButton =
++    gtk_toolbar_append_item(GTK_TOOLBAR(browser->toolbar),
++			    "Forward",
++			    "Forward",
++			    "Forward",
++			    0, // XXX replace with icon
++			    G_CALLBACK(forward_clicked_cb),
++			    browser);
++  // new reload button
++  browser->reloadButton = 
++    gtk_toolbar_append_item(GTK_TOOLBAR(browser->toolbar),
++			    "Reload",
++			    "Reload",
++			    "Reload",
++			    0, // XXX replace with icon
++			    G_CALLBACK(reload_clicked_cb),
++			    browser);
++  // create the url text entry
++  browser->urlEntry = gtk_entry_new();
++  // add it to the hbox
++  gtk_box_pack_start(GTK_BOX(browser->toolbarHBox), browser->urlEntry,
++		     TRUE, // expand
++		     TRUE, // fill
++		     0);    // padding
++  // create our new gtk moz embed widget
++  browser->mozEmbed = gtk_moz_embed_new();
++  gtk_moz_embed_push_startup();
++  // add it to the toplevel vbox
++  gtk_box_pack_start(GTK_BOX(browser->topLevelVBox), browser->mozEmbed,
++		     TRUE, // expand
++		     TRUE, // fill
++		     0);   // padding
++  // create the new hbox for the progress area
++  browser->progressAreaHBox = gtk_hbox_new(FALSE, 0);
++  // add it to the vbox
++  gtk_box_pack_start(GTK_BOX(browser->topLevelVBox), browser->progressAreaHBox,
++		     FALSE, // expand
++		     FALSE, // fill
++		     0);   // padding
++  // create our new progress bar
++  browser->progressBar = gtk_progress_bar_new();
++  // add it to the hbox
++  gtk_box_pack_start(GTK_BOX(browser->progressAreaHBox), browser->progressBar,
++		     FALSE, // expand
++		     FALSE, // fill
++		     0); // padding
++  
++  // create our status area and the alignment object that will keep it
++  // from expanding
++  browser->statusAlign = gtk_alignment_new(0, 0, 1, 1);
++  gtk_widget_set_size_request(browser->statusAlign, 1, -1);
++  // create the status bar
++  browser->statusBar = gtk_statusbar_new();
++  gtk_container_add(GTK_CONTAINER(browser->statusAlign), browser->statusBar);
++  // add it to the hbox
++  gtk_box_pack_start(GTK_BOX(browser->progressAreaHBox), browser->statusAlign,
++		     TRUE, // expand
++		     TRUE, // fill
++		     0);   // padding
++  // by default none of the buttons are marked as sensitive.
++  gtk_widget_set_sensitive(browser->backButton, FALSE);
++  gtk_widget_set_sensitive(browser->stopButton, FALSE);
++  gtk_widget_set_sensitive(browser->forwardButton, FALSE);
++  gtk_widget_set_sensitive(browser->reloadButton, FALSE);
++  
++  // catch the destruction of the toplevel window
++  g_signal_connect(GTK_OBJECT(browser->topLevelWindow), "delete_event",
++                   G_CALLBACK(delete_cb), browser);
++
++  // hook up the activate signal to the right callback
++  g_signal_connect(GTK_OBJECT(browser->urlEntry), "activate",
++                   G_CALLBACK(url_activate_cb), browser);
++
++  // hook up to the open new browser activation
++  g_signal_connect(GTK_OBJECT(browser->fileOpenNewBrowser), "activate",
++                   G_CALLBACK(menu_open_new_cb), browser);
++  // hook up to the stream test
++  g_signal_connect(GTK_OBJECT(browser->fileStream), "activate",
++                   G_CALLBACK(menu_stream_cb), browser);
++  // hook up the memory pressure release function
++  g_signal_connect(GTK_OBJECT(browser->fileMemory), "activate",
++                   G_CALLBACK(menu_memory_cb), browser);
++  // close this window
++  g_signal_connect(GTK_OBJECT(browser->fileClose), "activate",
++                   G_CALLBACK(menu_close_cb), browser);
++  // quit the application
++  g_signal_connect(GTK_OBJECT(browser->fileQuit), "activate",
++                   G_CALLBACK(menu_quit_cb), browser);
++
++  // hook up the location change to update the urlEntry
++  g_signal_connect(GTK_OBJECT(browser->mozEmbed), "location",
++                   G_CALLBACK(location_changed_cb), browser);
++  // hook up the title change to update the window title
++  g_signal_connect(GTK_OBJECT(browser->mozEmbed), "title",
++                   G_CALLBACK(title_changed_cb), browser);
++  // hook up the start and stop signals
++  g_signal_connect(GTK_OBJECT(browser->mozEmbed), "net_start",
++                   G_CALLBACK(load_started_cb), browser);
++  g_signal_connect(GTK_OBJECT(browser->mozEmbed), "net_stop",
++                   G_CALLBACK(load_finished_cb), browser);
++  // hook up to the change in network status
++  g_signal_connect(GTK_OBJECT(browser->mozEmbed), "net_state",
++                   G_CALLBACK(net_state_change_cb), browser);
++  g_signal_connect(GTK_OBJECT(browser->mozEmbed), "net_state_all",
++                   G_CALLBACK(net_state_change_all_cb), browser);
++  // hookup to changes in progress
++  g_signal_connect(GTK_OBJECT(browser->mozEmbed), "progress",
++                   G_CALLBACK(progress_change_cb), browser);
++  g_signal_connect(GTK_OBJECT(browser->mozEmbed), "progress_all",
++                   G_CALLBACK(progress_change_all_cb), browser);
++  // hookup to changes in over-link message
++  g_signal_connect(GTK_OBJECT(browser->mozEmbed), "link_message",
++                   G_CALLBACK(link_message_cb), browser);
++  // hookup to changes in js status message
++  g_signal_connect(GTK_OBJECT(browser->mozEmbed), "js_status",
++                   G_CALLBACK(js_status_cb), browser);
++  // hookup to see whenever a new window is requested
++  g_signal_connect(GTK_OBJECT(browser->mozEmbed), "new_window",
++                   G_CALLBACK(new_window_cb), browser);
++  // hookup to any requested visibility changes
++  g_signal_connect(GTK_OBJECT(browser->mozEmbed), "visibility",
++                   G_CALLBACK(visibility_cb), browser);
++  // hookup to the signal that says that the browser requested to be
++  // destroyed
++  g_signal_connect(GTK_OBJECT(browser->mozEmbed), "destroy_browser",
++                   G_CALLBACK(destroy_brsr_cb), browser);
++  // hookup to the signal that is called when someone clicks on a link
++  // to load a new uri
++  g_signal_connect(GTK_OBJECT(browser->mozEmbed), "open_uri",
++                   G_CALLBACK(open_uri_cb), browser);
++  // this signal is emitted when there's a request to change the
++  // containing browser window to a certain height, like with width
++  // and height args for a window.open in javascript
++  g_signal_connect(GTK_OBJECT(browser->mozEmbed), "size_to",
++                   G_CALLBACK(size_to_cb), browser);
++  // key event signals
++  g_signal_connect(GTK_OBJECT(browser->mozEmbed), "dom_key_down",
++                   G_CALLBACK(dom_key_down_cb), browser);
++  g_signal_connect(GTK_OBJECT(browser->mozEmbed), "dom_key_press",
++                   G_CALLBACK(dom_key_press_cb), browser);
++  g_signal_connect(GTK_OBJECT(browser->mozEmbed), "dom_key_up",
++                   G_CALLBACK(dom_key_up_cb), browser);
++  g_signal_connect(GTK_OBJECT(browser->mozEmbed), "dom_mouse_down",
++                   G_CALLBACK(dom_mouse_down_cb), browser);
++  g_signal_connect(GTK_OBJECT(browser->mozEmbed), "dom_mouse_up",
++                   G_CALLBACK(dom_mouse_up_cb), browser);
++  g_signal_connect(GTK_OBJECT(browser->mozEmbed), "dom_mouse_click",
++                   G_CALLBACK(dom_mouse_click_cb), browser);
++  g_signal_connect(GTK_OBJECT(browser->mozEmbed), "dom_mouse_dbl_click",
++                   G_CALLBACK(dom_mouse_dbl_click_cb), browser);
++  g_signal_connect(GTK_OBJECT(browser->mozEmbed), "dom_mouse_over",
++                   G_CALLBACK(dom_mouse_over_cb), browser);
++  g_signal_connect(GTK_OBJECT(browser->mozEmbed), "dom_mouse_out",
++                   G_CALLBACK(dom_mouse_out_cb), browser);
++  g_signal_connect(GTK_OBJECT(browser->mozEmbed), "dom_activate",
++                   G_CALLBACK(dom_activate_cb), browser);
++  g_signal_connect(GTK_OBJECT(browser->mozEmbed), "dom_focus_in",
++                   G_CALLBACK(dom_focus_in_cb), browser);
++  g_signal_connect(GTK_OBJECT(browser->mozEmbed), "dom_focus_out",
++                   G_CALLBACK(dom_focus_out_cb), browser);
++  // hookup to when the window is destroyed
++  g_signal_connect(GTK_OBJECT(browser->mozEmbed), "destroy",
++                   G_CALLBACK(destroy_cb), browser);
++  
++  // set the chrome type so it's stored in the object
++  gtk_moz_embed_set_chrome_mask(GTK_MOZ_EMBED(browser->mozEmbed),
++				actualChromeMask);
++
++  return browser;
++}
++
++void
++set_browser_visibility (TestGtkBrowser *browser, gboolean visibility)
++{
++  if (!visibility)
++  {
++    gtk_widget_hide(browser->topLevelWindow);
++    return;
++  }
++  
++  if (browser->menuBarOn)
++    gtk_widget_show_all(browser->menuBar);
++  else
++    gtk_widget_hide_all(browser->menuBar);
++
++  // since they are on the same line here...
++  if (browser->toolBarOn || browser->locationBarOn)
++    gtk_widget_show_all(browser->toolbarHBox);
++  else 
++    gtk_widget_hide_all(browser->toolbarHBox);
++
++  if (browser->statusBarOn)
++    gtk_widget_show_all(browser->progressAreaHBox);
++  else
++    gtk_widget_hide_all(browser->progressAreaHBox);
++
++  gtk_widget_show(browser->mozEmbed);
++  gtk_widget_show(browser->topLevelVBox);
++  gtk_widget_show(browser->topLevelWindow);
++}
++
++void
++back_clicked_cb (GtkButton *button, TestGtkBrowser *browser)
++{
++  gtk_moz_embed_go_back(GTK_MOZ_EMBED(browser->mozEmbed));
++}
++
++void
++stop_clicked_cb (GtkButton *button, TestGtkBrowser *browser)
++{
++  g_print("stop_clicked_cb\n");
++  gtk_moz_embed_stop_load(GTK_MOZ_EMBED(browser->mozEmbed));
++}
++
++void
++forward_clicked_cb (GtkButton *button, TestGtkBrowser *browser)
++{
++  g_print("forward_clicked_cb\n");
++  gtk_moz_embed_go_forward(GTK_MOZ_EMBED(browser->mozEmbed));
++}
++
++void
++reload_clicked_cb  (GtkButton *button, TestGtkBrowser *browser)
++{
++  g_print("reload_clicked_cb\n");
++  GdkModifierType state = (GdkModifierType)0;
++  gint x, y;
++  gdk_window_get_pointer(NULL, &x, &y, &state);
++  
++  gtk_moz_embed_reload(GTK_MOZ_EMBED(browser->mozEmbed),
++		       (state & GDK_SHIFT_MASK) ?
++		       GTK_MOZ_EMBED_FLAG_RELOADBYPASSCACHE : 
++		       GTK_MOZ_EMBED_FLAG_RELOADNORMAL);
++}
++
++void 
++stream_clicked_cb  (GtkButton   *button, TestGtkBrowser *browser)
++{
++  const char *data;
++  const char *data2;
++  data = "<html>Hi";
++  data2 = " there</html>\n";
++  g_print("stream_clicked_cb\n");
++  gtk_moz_embed_open_stream(GTK_MOZ_EMBED(browser->mozEmbed),
++			    "file://", "text/html");
++  gtk_moz_embed_append_data(GTK_MOZ_EMBED(browser->mozEmbed),
++			    data, strlen(data));
++  gtk_moz_embed_append_data(GTK_MOZ_EMBED(browser->mozEmbed),
++			    data2, strlen(data2));
++  gtk_moz_embed_close_stream(GTK_MOZ_EMBED(browser->mozEmbed));
++}
++
++void
++url_activate_cb    (GtkEditable *widget, TestGtkBrowser *browser)
++{
++  gchar *text = gtk_editable_get_chars(widget, 0, -1);
++  g_print("loading url %s\n", text);
++  gtk_moz_embed_load_url(GTK_MOZ_EMBED(browser->mozEmbed), text);
++  g_free(text);
++}
++
++void
++menu_open_new_cb   (GtkMenuItem *menuitem, TestGtkBrowser *browser)
++{
++  g_print("opening new browser.\n");
++  TestGtkBrowser *newBrowser = 
++    new_gtk_browser(GTK_MOZ_EMBED_FLAG_DEFAULTCHROME);
++  gtk_widget_set_size_request(newBrowser->mozEmbed, 400, 400);
++  set_browser_visibility(newBrowser, TRUE);
++}
++
++void
++menu_stream_cb     (GtkMenuItem *menuitem, TestGtkBrowser *browser)
++{
++  g_print("menu_stream_cb\n");
++  const char *data;
++  const char *data2;
++  data = "<html>Hi";
++  data2 = " <a href='foo.html'>there</a></html>\n";
++  g_print("stream_clicked_cb\n");
++  gtk_moz_embed_open_stream(GTK_MOZ_EMBED(browser->mozEmbed),
++			    "file://", "text/html");
++  gtk_moz_embed_append_data(GTK_MOZ_EMBED(browser->mozEmbed),
++			    data, strlen(data));
++  gtk_moz_embed_append_data(GTK_MOZ_EMBED(browser->mozEmbed),
++			    data2, strlen(data2));
++  gtk_moz_embed_close_stream(GTK_MOZ_EMBED(browser->mozEmbed));
++}
++
++void
++menu_memory_cb (GtkMenuItem *menuitem, TestGtkBrowser *browser)
++{
++  g_print("menu_memory_cb\n");
++  nsCOMPtr<nsIObserverService> os = do_GetService("@mozilla.org/observer-service;1");
++  if (!os)
++    return;
++
++  // Compact like you mean it.  We do this three times to give the
++  // cycle collector a chance to try and reclaim as much as we can.
++  os->NotifyObservers(nsnull, "memory-pressure", NS_LITERAL_STRING("heap-minimize").get());
++  os->NotifyObservers(nsnull, "memory-pressure", NS_LITERAL_STRING("heap-minimize").get());
++  os->NotifyObservers(nsnull, "memory-pressure", NS_LITERAL_STRING("heap-minimize").get());
++}
++
++void
++menu_close_cb (GtkMenuItem *menuitem, TestGtkBrowser *browser)
++{
++  gtk_widget_destroy(browser->topLevelWindow);
++}
++
++void
++menu_quit_cb (GtkMenuItem *menuitem, TestGtkBrowser *browser)
++{
++  TestGtkBrowser *tmpBrowser;
++  GList *tmp_list = browser_list;
++  tmpBrowser = (TestGtkBrowser *)tmp_list->data;
++  while (tmpBrowser) {
++    tmp_list = tmp_list->next;
++    gtk_widget_destroy(tmpBrowser->topLevelWindow);
++    tmpBrowser = (TestGtkBrowser *)tmp_list->data;
++  }
++}
++
++gboolean
++delete_cb(GtkWidget *widget, GdkEventAny *event, TestGtkBrowser *browser)
++{
++  g_print("delete_cb\n");
++  gtk_widget_destroy(widget);
++  return TRUE;
++}
++
++static gboolean
++idle_quit(void*)
++{
++  gtk_main_quit();
++  return FALSE;
++}
++
++static gboolean
++idle_pop(void*)
++{
++  gtk_moz_embed_pop_startup();
++  return FALSE;
++}
++
++void
++destroy_cb         (GtkWidget *widget, TestGtkBrowser *browser)
++{
++  GList *tmp_list;
++  g_print("destroy_cb\n");
++  num_browsers--;
++  tmp_list = g_list_find(browser_list, browser);
++  browser_list = g_list_remove_link(browser_list, tmp_list);
++  if (browser->tempMessage)
++    g_free(browser->tempMessage);
++  g_idle_add(idle_pop, NULL);
++  if (num_browsers == 0)
++    g_idle_add (idle_quit, NULL);
++}
++
++void
++location_changed_cb (GtkMozEmbed *embed, TestGtkBrowser *browser)
++{
++  char *newLocation;
++  int   newPosition = 0;
++  g_print("location_changed_cb\n");
++  newLocation = gtk_moz_embed_get_location(embed);
++  if (newLocation)
++  {
++    gtk_editable_delete_text(GTK_EDITABLE(browser->urlEntry), 0, -1);
++    gtk_editable_insert_text(GTK_EDITABLE(browser->urlEntry),
++			     newLocation, strlen(newLocation), &newPosition);
++    g_free(newLocation);
++  }
++  else
++    g_print("failed to get location!\n");
++  // always make sure to clear the tempMessage.  it might have been
++  // set from the link before a click and we wouldn't have gotten the
++  // callback to unset it.
++  update_temp_message(browser, 0);
++  // update the nav buttons on a location change
++  update_nav_buttons(browser);
++}
++
++void
++title_changed_cb    (GtkMozEmbed *embed, TestGtkBrowser *browser)
++{
++  char *newTitle;
++  g_print("title_changed_cb\n");
++  newTitle = gtk_moz_embed_get_title(embed);
++  if (newTitle)
++  {
++    gtk_window_set_title(GTK_WINDOW(browser->topLevelWindow), newTitle);
++    g_free(newTitle);
++  }
++  
++}
++
++void
++load_started_cb     (GtkMozEmbed *embed, TestGtkBrowser *browser)
++{
++  g_print("load_started_cb\n");
++  gtk_widget_set_sensitive(browser->stopButton, TRUE);
++  gtk_widget_set_sensitive(browser->reloadButton, FALSE);
++  browser->loadPercent = 0;
++  browser->bytesLoaded = 0;
++  browser->maxBytesLoaded = 0;
++  update_status_bar_text(browser);
++}
++
++void
++load_finished_cb    (GtkMozEmbed *embed, TestGtkBrowser *browser)
++{
++  g_print("load_finished_cb\n");
++  gtk_widget_set_sensitive(browser->stopButton, FALSE);
++  gtk_widget_set_sensitive(browser->reloadButton, TRUE);
++  browser->loadPercent = 0;
++  browser->bytesLoaded = 0;
++  browser->maxBytesLoaded = 0;
++  update_status_bar_text(browser);
++  gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(browser->progressBar), 0);
++}
++
++
++void
++net_state_change_cb (GtkMozEmbed *embed, gint flags, guint status,
++		     TestGtkBrowser *browser)
++{
++  g_print("net_state_change_cb %d\n", flags);
++  if (flags & GTK_MOZ_EMBED_FLAG_IS_REQUEST) {
++    if (flags & GTK_MOZ_EMBED_FLAG_REDIRECTING)
++    browser->statusMessage = "Redirecting to site...";
++    else if (flags & GTK_MOZ_EMBED_FLAG_TRANSFERRING)
++    browser->statusMessage = "Transferring data from site...";
++    else if (flags & GTK_MOZ_EMBED_FLAG_NEGOTIATING)
++    browser->statusMessage = "Waiting for authorization...";
++  }
++
++  if (status == GTK_MOZ_EMBED_STATUS_FAILED_DNS)
++    browser->statusMessage = "Site not found.";
++  else if (status == GTK_MOZ_EMBED_STATUS_FAILED_CONNECT)
++    browser->statusMessage = "Failed to connect to site.";
++  else if (status == GTK_MOZ_EMBED_STATUS_FAILED_TIMEOUT)
++    browser->statusMessage = "Failed due to connection timeout.";
++  else if (status == GTK_MOZ_EMBED_STATUS_FAILED_USERCANCELED)
++    browser->statusMessage = "User canceled connecting to site.";
++
++  if (flags & GTK_MOZ_EMBED_FLAG_IS_DOCUMENT) {
++    if (flags & GTK_MOZ_EMBED_FLAG_START)
++      browser->statusMessage = "Loading site...";
++    else if (flags & GTK_MOZ_EMBED_FLAG_STOP)
++      browser->statusMessage = "Done.";
++  }
++
++  update_status_bar_text(browser);
++  
++}
++
++void net_state_change_all_cb (GtkMozEmbed *embed, const char *uri,
++				     gint flags, guint status,
++				     TestGtkBrowser *browser)
++{
++  //  g_print("net_state_change_all_cb %s %d %d\n", uri, flags, status);
++}
++
++void progress_change_cb   (GtkMozEmbed *embed, gint cur, gint max,
++			   TestGtkBrowser *browser)
++{
++  g_print("progress_change_cb cur %d max %d\n", cur, max);
++
++  // avoid those pesky divide by zero errors
++  if (max < 1)
++  {
++    browser->loadPercent = 0;
++    browser->bytesLoaded = cur;
++    browser->maxBytesLoaded = 0;
++    update_status_bar_text(browser);
++  }
++  else
++  {
++    browser->bytesLoaded = cur;
++    browser->maxBytesLoaded = max;
++    if (cur > max)
++      browser->loadPercent = 100;
++    else
++      browser->loadPercent = (cur * 100) / max;
++    update_status_bar_text(browser);
++    gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(browser->progressBar),
++                                  browser->loadPercent / 100.0);
++  }
++  
++}
++
++void progress_change_all_cb (GtkMozEmbed *embed, const char *uri,
++			     gint cur, gint max,
++			     TestGtkBrowser *browser)
++{
++  //g_print("progress_change_all_cb %s cur %d max %d\n", uri, cur, max);
++}
++
++void
++link_message_cb      (GtkMozEmbed *embed, TestGtkBrowser *browser)
++{
++  char *message;
++  g_print("link_message_cb\n");
++  message = gtk_moz_embed_get_link_message(embed);
++  if (!message || !*message)
++    update_temp_message(browser, 0);
++  else
++    update_temp_message(browser, message);
++  if (message)
++    g_free(message);
++}
++
++void
++js_status_cb (GtkMozEmbed *embed, TestGtkBrowser *browser)
++{
++ char *message;
++  g_print("js_status_cb\n");
++  message = gtk_moz_embed_get_js_status(embed);
++  if (!message || !*message)
++    update_temp_message(browser, 0);
++  else
++    update_temp_message(browser, message);
++  if (message)
++    g_free(message);
++}
++
++void
++new_window_cb (GtkMozEmbed *embed, GtkMozEmbed **newEmbed, guint chromemask, TestGtkBrowser *browser)
++{
++  g_print("new_window_cb\n");
++  g_print("embed is %p chromemask is %d\n", (void *)embed, chromemask);
++  TestGtkBrowser *newBrowser = new_gtk_browser(chromemask);
++  gtk_widget_set_size_request(newBrowser->mozEmbed, 400, 400);
++  *newEmbed = GTK_MOZ_EMBED(newBrowser->mozEmbed);
++  g_print("new browser is %p\n", (void *)*newEmbed);
++}
++
++void
++visibility_cb (GtkMozEmbed *embed, gboolean visibility, TestGtkBrowser *browser)
++{
++  g_print("visibility_cb %d\n", visibility);
++  set_browser_visibility(browser, visibility);
++}
++
++void
++destroy_brsr_cb      (GtkMozEmbed *embed, TestGtkBrowser *browser)
++{
++  g_print("destroy_brsr_cb\n");
++  gtk_widget_destroy(browser->topLevelWindow);
++}
++
++gint
++open_uri_cb          (GtkMozEmbed *embed, const char *uri, TestGtkBrowser *browser)
++{
++  g_print("open_uri_cb %s\n", uri);
++
++  // interrupt this test load
++  if (!strcmp(uri, "http://people.redhat.com/blizzard/monkeys.txt"))
++    return TRUE;
++  // don't interrupt anything
++  return FALSE;
++}
++
++void
++size_to_cb (GtkMozEmbed *embed, gint width, gint height,
++	    TestGtkBrowser *browser)
++{
++  g_print("*** size_to_cb %d %d\n", width, height);
++  gtk_widget_set_size_request(browser->mozEmbed, width, height);
++}
++
++gint dom_key_down_cb      (GtkMozEmbed *embed, nsIDOMKeyEvent *event,
++			   TestGtkBrowser *browser)
++{
++  PRUint32 keyCode = 0;
++  //  g_print("dom_key_down_cb\n");
++  event->GetKeyCode(&keyCode);
++  // g_print("key code is %d\n", keyCode);
++  return NS_OK;
++}
++
++gint dom_key_press_cb     (GtkMozEmbed *embed, nsIDOMKeyEvent *event,
++			   TestGtkBrowser *browser)
++{
++  PRUint32 keyCode = 0;
++  // g_print("dom_key_press_cb\n");
++  event->GetCharCode(&keyCode);
++  // g_print("char code is %d\n", keyCode);
++  return NS_OK;
++}
++
++gint dom_key_up_cb        (GtkMozEmbed *embed, nsIDOMKeyEvent *event,
++			   TestGtkBrowser *browser)
++{
++  PRUint32 keyCode = 0;
++  // g_print("dom_key_up_cb\n");
++  event->GetKeyCode(&keyCode);
++  // g_print("key code is %d\n", keyCode);
++  return NS_OK;
++}
++
++gint dom_mouse_down_cb    (GtkMozEmbed *embed, nsIDOMMouseEvent *event,
++			   TestGtkBrowser *browser)
++{
++  //  g_print("dom_mouse_down_cb\n");
++  return NS_OK;
++ }
++
++gint dom_mouse_up_cb      (GtkMozEmbed *embed, nsIDOMMouseEvent *event,
++			   TestGtkBrowser *browser)
++{
++  //  g_print("dom_mouse_up_cb\n");
++  return NS_OK;
++}
++
++gint dom_mouse_click_cb   (GtkMozEmbed *embed, nsIDOMMouseEvent *event,
++			   TestGtkBrowser *browser)
++{
++  //  g_print("dom_mouse_click_cb\n");
++  PRUint16 button;
++  event->GetButton(&button);
++  printf("button was %d\n", button);
++  return NS_OK;
++}
++
++gint dom_mouse_dbl_click_cb (GtkMozEmbed *embed, nsIDOMMouseEvent *event,
++			     TestGtkBrowser *browser)
++{
++  //  g_print("dom_mouse_dbl_click_cb\n");
++  return NS_OK;
++}
++
++gint dom_mouse_over_cb    (GtkMozEmbed *embed, nsIDOMMouseEvent *event,
++			   TestGtkBrowser *browser)
++{
++  //g_print("dom_mouse_over_cb\n");
++  return NS_OK;
++}
++
++gint dom_mouse_out_cb     (GtkMozEmbed *embed, nsIDOMMouseEvent *event,
++			   TestGtkBrowser *browser)
++{
++  //g_print("dom_mouse_out_cb\n");
++  return NS_OK;
++}
++
++gint dom_activate_cb      (GtkMozEmbed *embed, nsIDOMUIEvent *event,
++			   TestGtkBrowser *browser)
++{
++  //g_print("dom_activate_cb\n");
++  return NS_OK;
++}
++
++gint dom_focus_in_cb      (GtkMozEmbed *embed, nsIDOMUIEvent *event,
++			   TestGtkBrowser *browser)
++{
++  //g_print("dom_focus_in_cb\n");
++  return NS_OK;
++}
++
++gint dom_focus_out_cb     (GtkMozEmbed *embed, nsIDOMUIEvent *event,
++			   TestGtkBrowser *browser)
++{
++  //g_print("dom_focus_out_cb\n");
++  return NS_OK;
++}
++
++void new_window_orphan_cb (GtkMozEmbedSingle *embed,
++			   GtkMozEmbed **retval, guint chromemask,
++			   gpointer data)
++{
++  g_print("new_window_orphan_cb\n");
++  g_print("chromemask is %d\n", chromemask);
++  TestGtkBrowser *newBrowser = new_gtk_browser(chromemask);
++  *retval = GTK_MOZ_EMBED(newBrowser->mozEmbed);
++  g_print("new browser is %p\n", (void *)*retval);
++}
++
++// utility functions
++
++void
++update_status_bar_text(TestGtkBrowser *browser)
++{
++  gchar message[256];
++  
++  gtk_statusbar_pop(GTK_STATUSBAR(browser->statusBar), 1);
++  if (browser->tempMessage)
++    gtk_statusbar_push(GTK_STATUSBAR(browser->statusBar), 1, browser->tempMessage);
++  else
++  {
++    if (browser->loadPercent)
++    {
++      g_snprintf(message, 255, "%s (%d%% complete, %d bytes of %d loaded)", browser->statusMessage, browser->loadPercent, browser->bytesLoaded, browser->maxBytesLoaded);
++    }
++    else if (browser->bytesLoaded)
++    {
++      g_snprintf(message, 255, "%s (%d bytes loaded)", browser->statusMessage, browser->bytesLoaded);
++    }
++    else if (browser->statusMessage == NULL)
++    {
++      g_snprintf(message, 255, " ");
++    }
++    else
++    {
++      g_snprintf(message, 255, "%s", browser->statusMessage);
++    }
++    gtk_statusbar_push(GTK_STATUSBAR(browser->statusBar), 1, message);
++  }
++}
++
++void
++update_temp_message(TestGtkBrowser *browser, const char *message)
++{
++  if (browser->tempMessage)
++    g_free(browser->tempMessage);
++  if (message)
++    browser->tempMessage = g_strdup(message);
++  else
++    browser->tempMessage = 0;
++  // now that we've updated the temp message, redraw the status bar
++  update_status_bar_text(browser);
++}
++
++
++void
++update_nav_buttons      (TestGtkBrowser *browser)
++{
++  gboolean can_go_back;
++  gboolean can_go_forward;
++  can_go_back = gtk_moz_embed_can_go_back(GTK_MOZ_EMBED(browser->mozEmbed));
++  can_go_forward = gtk_moz_embed_can_go_forward(GTK_MOZ_EMBED(browser->mozEmbed));
++  if (can_go_back)
++    gtk_widget_set_sensitive(browser->backButton, TRUE);
++  else
++    gtk_widget_set_sensitive(browser->backButton, FALSE);
++  if (can_go_forward)
++    gtk_widget_set_sensitive(browser->forwardButton, TRUE);
++  else
++    gtk_widget_set_sensitive(browser->forwardButton, FALSE);
++ }
++
+diff --git a/embedding/browser/gtk/tests/TestGtkEmbedChild.cpp b/embedding/browser/gtk/tests/TestGtkEmbedChild.cpp
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/tests/TestGtkEmbedChild.cpp
+@@ -0,0 +1,185 @@
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * Christopher Blizzard.
++ * Portions created by the Initial Developer are Copyright (C) 2001
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *   Christopher Blizzard <[email protected]>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#include "gtkmozembed.h"
++#include <gtk/gtk.h>
++#include <gdk/gdkx.h>
++#include <stdio.h>
++#include <stdlib.h>
++
++#include "nsStringAPI.h"
++#include "gtkmozembed_glue.cpp"
++
++int (*old_handler) (Display *, XErrorEvent *);
++
++int error_handler (Display *d, XErrorEvent *e)
++{
++  if ((e->error_code == BadWindow) || (e->error_code == BadDrawable))
++    {
++      XID resourceid = e->resourceid;
++      GdkWindow *window = gdk_window_lookup (resourceid);
++
++      if (window)
++        {
++          if (!g_dataset_get_data (window, "bonobo-error"))
++            {
++              g_dataset_set_data_full (window, "bonobo-error",
++                                       g_new (gint, 1),
++                                       (GDestroyNotify)g_free);
++
++              g_warning ("Error accessing window %ld", resourceid);
++            }
++        }
++      return 0;
++    }
++  else
++    {
++      return (*old_handler)(d, e);
++    }
++}
++
++void
++load_page(gpointer data);
++
++GtkWidget *embed = 0;
++GtkWidget *entry = 0;
++
++int
++main(int argc, char **argv)
++{
++  guint32 xid;
++
++  GtkWidget *window;
++  GtkWidget *hbox;
++  GtkWidget *vbox;
++  GtkWidget *button;
++
++  gtk_init(&argc, &argv);
++
++  static const GREVersionRange greVersion = {
++    "1.9a", PR_TRUE,
++    "2", PR_TRUE
++  };
++
++  char xpcomPath[PATH_MAX];
++
++  nsresult rv = GRE_GetGREPathWithProperties(&greVersion, 1, nsnull, 0,
++                                             xpcomPath, sizeof(xpcomPath));
++  if (NS_FAILED(rv)) {
++    fprintf(stderr, "Couldn't find a compatible GRE.\n");
++    return 1;
++  }
++
++  rv = XPCOMGlueStartup(xpcomPath);
++  if (NS_FAILED(rv)) {
++    fprintf(stderr, "Couldn't start XPCOM.");
++    return 1;
++  }
++
++  rv = GTKEmbedGlueStartup();
++  if (NS_FAILED(rv)) {
++    fprintf(stderr, "Couldn't find GTKMozEmbed symbols.");
++    return 1;
++  }
++
++  char *lastSlash = strrchr(xpcomPath, '/');
++  if (lastSlash)
++    *lastSlash = '\0';
++
++  gtk_moz_embed_set_path(xpcomPath);
++
++  old_handler = XSetErrorHandler (error_handler);
++
++  if (argc < 2) {
++    fprintf(stderr, "Usage: TestGtkEmbedChild WINDOW_ID\n");
++    exit(1);
++  }
++
++  xid = strtol (argv[1], (char **)NULL, 0);
++
++  if (xid == 0) {
++    fprintf(stderr, "Invalid window id '%s'\n", argv[1]);
++    exit(1);
++  }
++
++  window = gtk_plug_new(xid);
++
++  g_signal_connect(GTK_OBJECT(window), "destroy",
++                   G_CALLBACK(gtk_main_quit), NULL);
++
++  gtk_container_set_border_width(GTK_CONTAINER(window), 0);
++
++  vbox = gtk_vbox_new (FALSE, 0);
++  gtk_container_add(GTK_CONTAINER(window), vbox);
++  gtk_widget_show(vbox);
++
++  hbox = gtk_hbox_new (FALSE, 0);
++  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
++  gtk_widget_show (hbox);
++
++  entry = gtk_entry_new ();
++  gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
++  gtk_widget_show (entry);
++
++  button = gtk_button_new_with_label("Load");
++  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
++  gtk_widget_show(button);
++
++  g_signal_connect(GTK_OBJECT(button), "clicked", G_CALLBACK(load_page), NULL);
++
++  embed = gtk_moz_embed_new();
++  gtk_box_pack_start(GTK_BOX(vbox), embed, TRUE, TRUE, 0);
++  gtk_widget_set_size_request(embed, 200, 200);
++  gtk_widget_show(embed);
++
++  gtk_widget_show(window);
++  
++  gtk_main();
++
++  fprintf(stderr, "exiting.\n");
++
++  return 0;
++}
++
++void
++load_page(gpointer data)
++{
++  gchar *text = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
++  g_print("load url %s\n", text);
++  gtk_moz_embed_load_url(GTK_MOZ_EMBED(embed), text);
++  g_free(text);
++}
+diff --git a/embedding/browser/gtk/tests/TestGtkEmbedMDI.cpp b/embedding/browser/gtk/tests/TestGtkEmbedMDI.cpp
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/tests/TestGtkEmbedMDI.cpp
+@@ -0,0 +1,142 @@
++/** simplemdi.c **/
++/*
++ * Sample code from "GNOME/GTK+ Programming Bible" by Arthur Griffith
++ * Modified by Kevin Gibbs ([email protected]) to provide sample of
++ * GtkMozEmbed realization/unrealization crashes.
++ *
++ * To get a fatal crash, simply run the program, click on the "Mozilla"
++ * tab to display the MozEmbed widget, and then try to drag that MDI tab
++ * off to a new window.
++ * 
++ * Although this test might seem elaborate, it is really only a convenient
++ * to create a situation where the widget is realized, unrealized, and
++ * realized again at some point. (Dragging the MDI tab off to a new window
++ * causes all widgets to be unrealized in the old window, and then realized
++ * again in the new window.) 
++ */
++
++#include <gnome.h>
++#include "gtkmozembed.h"
++
++// Testing flags
++//
++
++// Define this flag to have the test program use the gtkmozembed widget.
++// Without this flag, mozilla is never loaded in the program, and a simple
++// widget is used in place of the mozembed widget.
++#define USE_MOZILLA_TEST
++
++// Define this flag to have a simpler test than the usual one. The normal
++// test builds a notebook inside of each MDI view, with one page being a label
++// and the other page being a browser widget. The simpler test does not
++// build a notebook and simply puts the browser widget in the MDI view itself.
++// Currently, this test is not very interesting, since for some reason all
++// the webshells just create and destroy themselves. (???)
++//#define SIMPLER_TEST
++
++// Define this flag to use a GnomePixmap instead of a GtkLabel as the
++// replacement for the gtkmozembed widget when USE_MOZILLA_TEST is
++// undefined. This is to stress test the program a bit more by providing a
++// replacement widget slightly more complex than GtkLabel.
++// (Has no effect when USE_MOZILLA_TEST is defined.)
++#define SAMPLE_PIXMAP
++
++
++gint eventDelete(GtkWidget *widget,
++        GdkEvent *event,gpointer data);
++gint eventDestroy(GtkWidget *widget,
++        GdkEvent *event,gpointer data);
++
++static void addChild(GtkObject *mdi,gchar *name);
++static GtkWidget *setLabel(GnomeMDIChild *child,
++        GtkWidget *currentLabel,gpointer data);
++static GtkWidget *createView(GnomeMDIChild *child,
++        gpointer data);
++
++int main(int argc,char *argv[])
++{
++    GtkObject *mdi;
++
++    gnome_init("simplemdi","1.0",argc,argv);
++    mdi = gnome_mdi_new("simplemdi","Simple MDI");
++    gtk_signal_connect(mdi,"destroy",
++            GTK_SIGNAL_FUNC(eventDestroy),NULL);
++
++    addChild(mdi,"First");
++    addChild(mdi,"Second");
++    addChild(mdi,"Third");
++    addChild(mdi,"Last");
++
++    gnome_mdi_set_mode(GNOME_MDI(mdi),GNOME_MDI_NOTEBOOK);
++    //gnome_mdi_open_toplevel(GNOME_MDI(mdi));
++
++    gtk_main();
++    exit(0);
++}
++static void addChild(GtkObject *mdi,gchar *name)
++{
++    GnomeMDIGenericChild *child;
++
++    child = gnome_mdi_generic_child_new(name);
++    gnome_mdi_add_child(GNOME_MDI(mdi),
++            GNOME_MDI_CHILD(child));
++
++    gnome_mdi_generic_child_set_view_creator(child,
++            createView,name);
++    gnome_mdi_generic_child_set_label_func(child,setLabel,
++            NULL);
++    gnome_mdi_add_view(GNOME_MDI(mdi),
++            GNOME_MDI_CHILD(child));
++}
++static GtkWidget *createView(GnomeMDIChild *child,
++        gpointer data)
++{
++#ifdef USE_MOZILLA_TEST
++    GtkWidget *browser = gtk_moz_embed_new();
++#else
++#ifndef SAMPLE_PIXMAP
++    GtkWidget *browser = gtk_label_new("lynx 0.01a");
++#else
++    /* Another example -- */
++    GtkWidget *browser =
++      gnome_pixmap_new_from_file("/usr/share/pixmaps/emacs.png");
++#endif /* SAMPLE_PIXMAP */
++#endif /* USE_MOZILLA_TEST */
++
++    GtkWidget *notebook = gtk_notebook_new();
++    char str[80];
++
++    sprintf(str,"View of the\n%s widget",(gchar *)data);
++
++#ifdef USE_MOZILLA_TEST
++    gtk_moz_embed_load_url(GTK_MOZ_EMBED(browser), "http://www.mozilla.org");
++#endif /* USE_MOZILLA_TEST */
++
++#ifndef SIMPLER_TEST
++    gtk_notebook_append_page(GTK_NOTEBOOK(notebook), gtk_label_new(str),
++			     gtk_label_new("Label"));
++    gtk_notebook_append_page(GTK_NOTEBOOK(notebook), browser,
++			     gtk_label_new("Mozilla"));
++    gtk_widget_show_all(notebook);
++    return (notebook);
++#else
++    gtk_widget_show(browser);
++    return (browser);
++#endif /* SIMPLER_TEST */
++}
++
++static GtkWidget *setLabel(GnomeMDIChild *child,
++        GtkWidget *currentLabel,gpointer data)
++{
++    if(currentLabel == NULL)
++        return(gtk_label_new(child->name));
++
++    gtk_label_set_text(GTK_LABEL(currentLabel),
++            child->name);
++    return(currentLabel);
++}
++gint eventDestroy(GtkWidget *widget,
++        GdkEvent *event,gpointer data) {
++    gtk_main_quit();
++    return(0);
++}
+diff --git a/embedding/browser/gtk/tests/TestGtkEmbedNotebook.cpp b/embedding/browser/gtk/tests/TestGtkEmbedNotebook.cpp
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/tests/TestGtkEmbedNotebook.cpp
+@@ -0,0 +1,86 @@
++#include <gtk/gtk.h>
++#include <gtkmozembed.h>
++#include <stdio.h>
++#include "nsStringAPI.h"
++#include "gtkmozembed_glue.cpp"
++
++int main(int argc, char *argv[])
++{
++	GtkWidget *window;
++	GtkWidget *label;
++	GtkWidget *mozembed;
++	GtkWidget *container;
++	char *url;
++
++	gtk_init(&argc, &argv);
++	
++        static const GREVersionRange greVersion = {
++                "1.9a", PR_TRUE,
++                "2", PR_TRUE
++        };
++
++        char xpcomPath[PATH_MAX];
++
++        nsresult rv =
++                GRE_GetGREPathWithProperties(&greVersion, 1, nsnull, 0,
++                                             xpcomPath, sizeof(xpcomPath));
++        if (NS_FAILED(rv)) {
++                fprintf(stderr, "Couldn't find a compatible GRE.\n");
++                return 1;
++        }
++
++        rv = XPCOMGlueStartup(xpcomPath);
++        if (NS_FAILED(rv)) {
++                fprintf(stderr, "Couldn't start XPCOM.");
++                return 1;
++        }
++
++        rv = GTKEmbedGlueStartup();
++        if (NS_FAILED(rv)) {
++                fprintf(stderr, "Couldn't find GTKMozEmbed symbols.");
++                return 1;
++        }
++
++        char *lastSlash = strrchr(xpcomPath, '/');
++        if (lastSlash)
++                *lastSlash = '\0';
++
++        gtk_moz_embed_set_path(xpcomPath);
++
++	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
++	
++	container = gtk_notebook_new();
++	mozembed = gtk_moz_embed_new();
++	label = gtk_label_new("Can you see this message?\n"
++			      "Once you switch to mozembed page " 
++			      "you never see this message.");
++
++	g_signal_connect(GTK_OBJECT(mozembed), "destroy",
++	                 G_CALLBACK(gtk_main_quit),
++NULL);
++
++	gtk_container_add(GTK_CONTAINER(window), container);
++
++	gtk_notebook_append_page(GTK_NOTEBOOK(container),
++			label,
++			gtk_label_new("gtk label"));
++
++	gtk_notebook_append_page(GTK_NOTEBOOK(container),
++			mozembed,
++			gtk_label_new("mozembed"));
++
++
++
++
++	gtk_widget_set_size_request(window, 400, 300);
++	gtk_widget_show(mozembed);
++	gtk_widget_show(label);
++	gtk_widget_show_all(window);
++
++	url = (argc > 1) ? argv[1] : (char *)"localhost";
++	gtk_moz_embed_load_url(GTK_MOZ_EMBED(mozembed), url);
++
++	gtk_main();
++	
++	return 0;
++}
+diff --git a/embedding/browser/gtk/tests/TestGtkEmbedSocket.cpp b/embedding/browser/gtk/tests/TestGtkEmbedSocket.cpp
+new file mode 100644
+--- /dev/null
++++ b/embedding/browser/gtk/tests/TestGtkEmbedSocket.cpp
+@@ -0,0 +1,109 @@
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * Christopher Blizzard.
++ * Portions created by the Initial Developer are Copyright (C) 2001
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *   Christopher Blizzard <[email protected]>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#include <gtk/gtk.h>
++#include <gdk/gdkx.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <sys/types.h>
++#include <unistd.h>
++
++GtkWidget *toplevel_window = 0;
++GtkWidget *button = 0;
++GtkWidget *vbox = 0;
++GtkWidget *gtk_socket = 0;
++
++void
++insert_mozilla(gpointer data);
++
++int
++main(int argc, char **argv)
++{
++  gtk_init(&argc, &argv);
++
++  toplevel_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
++
++  g_signal_connect(GTK_OBJECT(toplevel_window), "destroy",
++                   G_CALLBACK(exit), NULL);
++
++  vbox = gtk_vbox_new(FALSE, 0);
++  gtk_container_add(GTK_CONTAINER(toplevel_window), vbox);
++  gtk_widget_show(vbox);
++
++  button = gtk_button_new_with_label("Insert Mozilla");
++
++  gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
++  gtk_widget_show(button);
++
++  g_signal_connect(GTK_OBJECT(button), "clicked",
++                   G_CALLBACK(insert_mozilla), NULL);
++
++  gtk_widget_show(toplevel_window);
++
++  gtk_main();
++
++  return 0;
++}
++
++void
++insert_mozilla(gpointer data)
++{
++  char buffer[20];
++  int pid;
++
++  if (gtk_socket)
++    return;
++
++  gtk_socket = gtk_socket_new();
++  gtk_box_pack_start(GTK_BOX(vbox), gtk_socket, TRUE, TRUE, 0);
++  gtk_widget_show(gtk_socket);
++
++  sprintf(buffer, "%#lx", GDK_WINDOW_XWINDOW(gtk_socket->window));
++
++  gdk_flush();
++
++  if ((pid = fork()) == 0) { /* child */
++    execl("./TestGtkEmbedChild", "./TestGtkEmbedChild", buffer, NULL);
++    fprintf(stderr, "can't exec child\n");
++    _exit(1);
++  }
++  else if (pid > 0) { /* parent */
++  }
++  else {
++    fprintf(stderr, "Can't fork.\n");
++  }
++}
+diff --git a/toolkit/toolkit-makefiles.sh b/toolkit/toolkit-makefiles.sh
+--- a/toolkit/toolkit-makefiles.sh
++++ b/toolkit/toolkit-makefiles.sh
+@@ -547,16 +547,19 @@ MAKEFILES_embedding="
+   embedding/browser/Makefile
+   embedding/browser/activex/src/Makefile
+   embedding/browser/activex/src/common/Makefile
+   embedding/browser/activex/src/control/Makefile
+   embedding/browser/activex/src/control_kicker/Makefile
+   embedding/browser/activex/src/plugin/Makefile
+   embedding/browser/build/Makefile
+   embedding/browser/webBrowser/Makefile
++  embedding/browser/gtk/Makefile
++  embedding/browser/gtk/src/Makefile
++  embedding/browser/gtk/tests/Makefile
+   embedding/components/Makefile
+   embedding/components/appstartup/Makefile
+   embedding/components/appstartup/src/Makefile
+   embedding/components/build/Makefile
+   embedding/components/commandhandler/Makefile
+   embedding/components/commandhandler/public/Makefile
+   embedding/components/commandhandler/src/Makefile
+   embedding/components/find/Makefile
+diff --git a/toolkit/library/Makefile.in b/toolkit/library/Makefile.in
+--- a/toolkit/library/Makefile.in
++++ b/toolkit/library/Makefile.in
+@@ -80,6 +80,13 @@
+ DEFINES += -DMOZ_ENABLE_GTK2
+ endif
+ 
++# dependent libraries
++ifneq (,$(MOZ_ENABLE_GTK2))
++SHARED_LIBRARY_LIBS += \
++  $(DEPTH)/embedding/browser/gtk/src/$(LIB_PREFIX)gtkembedmoz.$(LIB_SUFFIX)
++DEFINES += -DMOZ_ENABLE_GTK2
++endif
++
+ SHARED_LIBRARY_LIBS += \
+ 	$(DEPTH)/toolkit/xre/$(LIB_PREFIX)xulapp_s.$(LIB_SUFFIX) \
+ 	$(NULL)
+diff --git a/toolkit/toolkit-tiers.mk b/toolkit/toolkit-tiers.mk
+--- a/toolkit/toolkit-tiers.mk
++++ b/toolkit/toolkit-tiers.mk
+@@ -223,6 +223,12 @@
+ 
+ tier_platform_dirs += services/crypto/component
+ 
++ifndef BUILD_STATIC_LIBS
++ifneq (,$(MOZ_ENABLE_GTK2))
++tier_platform_dirs += embedding/browser/gtk
++endif
++endif
++
+ tier_platform_dirs += startupcache
+ 
+ ifdef APP_LIBXUL_STATICDIRS
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/firefox6-37-glxtest.diff	Mon Aug 15 02:22:00 2011 +0000
@@ -0,0 +1,24 @@
+diff --git a/toolkit/xre/glxtest.cpp b/toolkit/xre/glxtest.cpp
+--- a/toolkit/xre/glxtest.cpp
++++ b/toolkit/xre/glxtest.cpp
+@@ -54,16 +54,20 @@
+ #include <cstdio>
+ #include <cstdlib>
+ #include <unistd.h>
+ #include <GL/gl.h>
+ #include <GL/glx.h>
+ #include <dlfcn.h>
+ #include "nscore.h"
+ 
++#ifdef SOLARIS
++#include <stdio.h>
++#endif
++
+ namespace mozilla {
+ namespace widget {
+ // the read end of the pipe, which will be used by GfxInfo
+ extern int glxtest_pipe;
+ // the PID of the glxtest process, to pass to waitpid()
+ extern pid_t glxtest_pid;
+ }
+ }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/firefox6-38-copy-paste-key.diff	Mon Aug 15 02:22:00 2011 +0000
@@ -0,0 +1,292 @@
+diff --git a/content/xbl/builtin/emacs/platformHTMLBindings.xml b/content/xbl/builtin/emacs/platformHTMLBindings.xml
+--- a/content/xbl/builtin/emacs/platformHTMLBindings.xml
++++ b/content/xbl/builtin/emacs/platformHTMLBindings.xml
+@@ -64,20 +64,16 @@
+     <handler event="keypress" keycode="VK_LEFT" modifiers="shift,control" 
+         command="cmd_selectWordPrevious"/>
+     <handler event="keypress" keycode="VK_RIGHT" modifiers="shift,control" 
+         command="cmd_selectWordNext"/>
+     <handler event="keypress" key="y" modifiers="accel"
+         command="cmd_redo"/>
+     <handler event="keypress" key="a" modifiers="alt"
+         command="cmd_selectAll"/>
+-    <handler event="keypress" keycode="VK_F20" command="cmd_cut" />
+-    <handler event="keypress" keycode="VK_F16" command="cmd_copy" />
+-    <handler event="keypress" keycode="VK_F18" command="cmd_paste" />
+-    <handler event="keypress" keycode="VK_F14" command="cmd_undo" />
+     </handlers>
+   </binding>
+ 
+   <binding id="textAreas">
+     <handlers>
+ #include ../textareas-base.inc
+     <!-- Emacsish single-line motion and delete keys -->
+     <handler event="keypress" key="a" modifiers="control"
+@@ -152,20 +148,16 @@
+     <handler event="keypress" keycode="VK_RIGHT" modifiers="shift,control" 
+         command="cmd_selectWordNext"/>
+     <handler event="keypress" keycode="VK_BACK" modifiers="control"
+         command="cmd_deleteWordBackward"/>
+     <handler event="keypress" key="y" modifiers="accel"
+         command="cmd_redo"/>
+     <handler event="keypress" key="a" modifiers="alt"
+         command="cmd_selectAll"/>
+-    <handler event="keypress" keycode="VK_F20" command="cmd_cut" />
+-    <handler event="keypress" keycode="VK_F16" command="cmd_copy" />
+-    <handler event="keypress" keycode="VK_F18" command="cmd_paste" />
+-    <handler event="keypress" keycode="VK_F14" command="cmd_undo" />
+     </handlers>
+   </binding>
+ 
+   <binding id="browser">
+     <handlers>
+ #include ../browser-base.inc
+       <handler event="keypress" keycode="VK_PAGE_UP" command="cmd_movePageUp"/>
+       <handler event="keypress" keycode="VK_PAGE_DOWN" command="cmd_movePageDown"/>
+@@ -177,20 +169,16 @@
+       <handler event="keypress" keycode="VK_INSERT" modifiers="control" command="cmd_copy" /> 
+       <handler event="keypress" keycode="VK_HOME" command="cmd_beginLine"/>
+       <handler event="keypress" keycode="VK_END" command="cmd_endLine"/>
+       <handler event="keypress" keycode="VK_HOME" modifiers="control" command="cmd_scrollTop"/>
+       <handler event="keypress" keycode="VK_END" modifiers="control" command="cmd_scrollBottom"/>
+       <handler event="keypress" keycode="VK_HOME" modifiers="shift,control" command="cmd_selectTop" /> 
+       <handler event="keypress" keycode="VK_END" modifiers="shift,control" command="cmd_selectBottom" /> 
+ 
+-      <handler event="keypress" keycode="VK_F20" command="cmd_cut" /> 
+-      <handler event="keypress" keycode="VK_F16" command="cmd_copy" /> 
+-      <handler event="keypress" keycode="VK_F18" command="cmd_paste" /> 
+-      <handler event="keypress" keycode="VK_F14" command="cmd_undo" />
+       <handler event="keypress" keycode="VK_LEFT" modifiers="control" command="cmd_wordPrevious" />
+       <handler event="keypress" keycode="VK_RIGHT" modifiers="control" command="cmd_wordNext" />
+       <handler event="keypress" keycode="VK_LEFT" modifiers="control,shift" command="cmd_selectWordPrevious" />
+       <handler event="keypress" keycode="VK_RIGHT" modifiers="control,shift" command="cmd_selectWordNext" />
+       <handler event="keypress" keycode="VK_LEFT" modifiers="shift" command="cmd_selectCharPrevious" />
+       <handler event="keypress" keycode="VK_RIGHT" modifiers="shift" command="cmd_selectCharNext" />
+       <handler event="keypress" keycode="VK_HOME" modifiers="shift" command="cmd_selectBeginLine" />
+       <handler event="keypress" keycode="VK_END" modifiers="shift" command="cmd_selectEndLine" />
+@@ -235,15 +223,11 @@
+       <handler event="keypress" keycode="VK_HOME" modifiers="shift,control" command="cmd_selectTop"/>
+       <handler event="keypress" keycode="VK_END" modifiers="shift,control" command="cmd_selectBottom"/>
+       <handler event="keypress" keycode="VK_HOME" modifiers="control" command="cmd_moveTop"/>
+       <handler event="keypress" keycode="VK_END" modifiers="control" command="cmd_moveBottom"/>
+       <handler event="keypress" keycode="VK_PAGE_UP" command="cmd_movePageUp"/>
+       <handler event="keypress" keycode="VK_PAGE_DOWN" command="cmd_movePageDown"/>
+       <handler event="keypress" keycode="VK_PAGE_UP" modifiers="shift" command="cmd_selectPageUp"/>
+       <handler event="keypress" keycode="VK_PAGE_DOWN" modifiers="shift" command="cmd_selectPageDown"/>
+-      <handler event="keypress" keycode="VK_F20" command="cmd_cut" />
+-      <handler event="keypress" keycode="VK_F16" command="cmd_copy" />
+-      <handler event="keypress" keycode="VK_F18" command="cmd_paste" />
+-      <handler event="keypress" keycode="VK_F14" command="cmd_undo" />
+     </handlers>
+   </binding>
+ </bindings>
+diff --git a/content/xbl/builtin/unix/platformHTMLBindings.xml b/content/xbl/builtin/unix/platformHTMLBindings.xml
+--- a/content/xbl/builtin/unix/platformHTMLBindings.xml
++++ b/content/xbl/builtin/unix/platformHTMLBindings.xml
+@@ -8,33 +8,28 @@
+     <handlers>
+ #include ../input-fields-base.inc
+     <handler event="keypress" key="a" modifiers="alt"
+         command="cmd_selectAll"/>
+     <handler event="keypress" key="y" modifiers="accel"
+         command="cmd_redo"/>
+     <handler event="keypress" key="z" modifiers="accel,shift" command="cmd_redo"/>
+     <handler event="keypress" key="z" modifiers="accel" command="cmd_undo"/>
+-    <handler event="keypress" keycode="VK_F14" command="cmd_undo" />
+     </handlers>
+   </binding>
+ 
+   <binding id="textAreas">
+     <handlers>
+ #include ../textareas-base.inc
+     <handler event="keypress" key="a" modifiers="alt"
+         command="cmd_selectAll"/>
+     <handler event="keypress" key="y" modifiers="accel"
+         command="cmd_redo"/>
+     <handler event="keypress" key="z" modifiers="accel" command="cmd_undo"/>
+     <handler event="keypress" key="z" modifiers="accel,shift" command="cmd_redo"/>
+-    <handler event="keypress" keycode="VK_F20" command="cmd_cut" />
+-    <handler event="keypress" keycode="VK_F16" command="cmd_copy" />
+-    <handler event="keypress" keycode="VK_F18" command="cmd_paste" />
+-    <handler event="keypress" keycode="VK_F14" command="cmd_undo" />
+     </handlers>
+   </binding>
+ 
+   <binding id="browser">
+     <handlers>
+ #include ../browser-base.inc
+       <handler event="keypress" keycode="VK_PAGE_UP" command="cmd_movePageUp"/>
+       <handler event="keypress" keycode="VK_PAGE_DOWN" command="cmd_movePageDown"/>
+@@ -46,20 +41,16 @@
+       <handler event="keypress" keycode="VK_INSERT" modifiers="control" command="cmd_copy" /> 
+       <handler event="keypress" keycode="VK_HOME" command="cmd_beginLine"/>
+       <handler event="keypress" keycode="VK_END" command="cmd_endLine"/>
+       <handler event="keypress" keycode="VK_HOME" modifiers="control" command="cmd_scrollTop"/>
+       <handler event="keypress" keycode="VK_END" modifiers="control" command="cmd_scrollBottom"/>
+       <handler event="keypress" keycode="VK_HOME" modifiers="shift,control" command="cmd_selectTop" /> 
+       <handler event="keypress" keycode="VK_END" modifiers="shift,control" command="cmd_selectBottom" /> 
+ 
+-      <handler event="keypress" keycode="VK_F20" command="cmd_cut" /> 
+-      <handler event="keypress" keycode="VK_F16" command="cmd_copy" /> 
+-      <handler event="keypress" keycode="VK_F18" command="cmd_paste" /> 
+-      <handler event="keypress" keycode="VK_F14" command="cmd_undo" />
+       <handler event="keypress" keycode="VK_LEFT" modifiers="control" command="cmd_wordPrevious" />
+       <handler event="keypress" keycode="VK_RIGHT" modifiers="control" command="cmd_wordNext" />
+       <handler event="keypress" keycode="VK_LEFT" modifiers="control,shift" command="cmd_selectWordPrevious" />
+       <handler event="keypress" keycode="VK_RIGHT" modifiers="control,shift" command="cmd_selectWordNext" />
+       <handler event="keypress" keycode="VK_LEFT" modifiers="shift" command="cmd_selectCharPrevious" />
+       <handler event="keypress" keycode="VK_RIGHT" modifiers="shift" command="cmd_selectCharNext" />
+       <handler event="keypress" keycode="VK_HOME" modifiers="shift" command="cmd_selectBeginLine" />
+       <handler event="keypress" keycode="VK_END" modifiers="shift" command="cmd_selectEndLine" />
+@@ -71,15 +62,11 @@
+ 
+   <binding id="editor">
+     <handlers>
+ #include ../editor-base.inc
+       <handler event="keypress" key="z" modifiers="accel" command="cmd_undo"/>
+       <handler event="keypress" key="z" modifiers="accel,shift" command="cmd_redo"/>
+       <handler event="keypress" key="y" modifiers="accel"   command="cmd_redo"/>
+       <handler event="keypress" key="a" modifiers="alt" command="cmd_selectAll"/>
+-      <handler event="keypress" keycode="VK_F20" command="cmd_cut" />
+-      <handler event="keypress" keycode="VK_F16" command="cmd_copy" />
+-      <handler event="keypress" keycode="VK_F18" command="cmd_paste" />
+-      <handler event="keypress" keycode="VK_F14" command="cmd_undo" />
+     </handlers>
+   </binding>
+ </bindings>
+diff --git a/widget/src/gtk2/nsWindow.h b/widget/src/gtk2/nsWindow.h
+--- a/widget/src/gtk2/nsWindow.h
++++ b/widget/src/gtk2/nsWindow.h
+@@ -377,16 +377,17 @@ private:
+     GtkWidget         *GetMozContainerWidget();
+     nsWindow          *GetContainerWindow();
+     void               SetUrgencyHint(GtkWidget *top_window, PRBool state);
+     void              *SetupPluginPort(void);
+     nsresult           SetWindowIconList(const nsTArray<nsCString> &aIconList);
+     void               SetDefaultIcon(void);
+     void               InitButtonEvent(nsMouseEvent &aEvent, GdkEventButton *aGdkEvent);
+     PRBool             DispatchCommandEvent(nsIAtom* aCommand);
++    PRBool             DispatchContentCommandEvent(PRInt32 aMsg);
+     void               SetWindowClipRegion(const nsTArray<nsIntRect>& aRects,
+                                            PRBool aIntersectWithExisting);
+     PRBool             GetDragInfo(nsMouseEvent* aMouseEvent,
+                                    GdkWindow** aWindow, gint* aButton,
+                                    gint* aRootX, gint* aRootY);
+     void               ClearCachedResources();
+ 
+     GtkWidget          *mShell;
+diff --git a/widget/src/gtk2/nsWindow.cpp b/widget/src/gtk2/nsWindow.cpp
+--- a/widget/src/gtk2/nsWindow.cpp
++++ b/widget/src/gtk2/nsWindow.cpp
+@@ -63,13 +63,6 @@
+ #include <X11/Xatom.h>
+ #include <X11/extensions/XShm.h>
+ #include <X11/extensions/shape.h>
+-
+-#ifdef AIX
+-#include <X11/keysym.h>
+-#else
+-#include <X11/XF86keysym.h>
+-#endif
+-
+ #include "gtk2xtbin.h"
+ #endif /* MOZ_X11 */
+ #include <gdk/gdkkeysyms.h>
+@@ -2992,6 +2985,15 @@
+     return TRUE;
+ }
+ 
++PRBool
++nsWindow::DispatchContentCommandEvent(PRInt32 aMsg)
++{
++  nsEventStatus status;
++  nsContentCommandEvent event(PR_TRUE, aMsg, this);
++  DispatchEvent(&event, status);
++  return TRUE;
++}
++
+ static PRUint32
+ GetCharCodeFor(const GdkEventKey *aEvent, guint aShiftState,
+                gint aGroup)
+@@ -3120,27 +3122,37 @@
+         return TRUE;
+     }
+ 
+-#ifdef MOZ_X11
+-#if ! defined AIX // no XFree86 on AIX 5L
+     // Look for specialized app-command keys
+     switch (aEvent->keyval) {
+-        case XF86XK_Back:
++        case GDK_Back:
+             return DispatchCommandEvent(nsWidgetAtoms::Back);
+-        case XF86XK_Forward:
++        case GDK_Forward:
+             return DispatchCommandEvent(nsWidgetAtoms::Forward);
+-        case XF86XK_Refresh:
++        case GDK_Refresh:
+             return DispatchCommandEvent(nsWidgetAtoms::Reload);
+-        case XF86XK_Stop:
++        case GDK_Stop:
+             return DispatchCommandEvent(nsWidgetAtoms::Stop);
+-        case XF86XK_Search:
++        case GDK_Search:
+             return DispatchCommandEvent(nsWidgetAtoms::Search);
+-        case XF86XK_Favorites:
++        case GDK_Favorites:
+             return DispatchCommandEvent(nsWidgetAtoms::Bookmarks);
+-        case XF86XK_HomePage:
++        case GDK_HomePage:
+             return DispatchCommandEvent(nsWidgetAtoms::Home);
++        case GDK_Copy:
++        case GDK_F16:  // F16, F20, F18, F14 are old keysyms for Copy Cut Paste Undo
++            return DispatchContentCommandEvent(NS_CONTENT_COMMAND_COPY);
++        case GDK_Cut:
++        case GDK_F20:
++            return DispatchContentCommandEvent(NS_CONTENT_COMMAND_CUT);
++        case GDK_Paste:
++        case GDK_F18:
++            return DispatchContentCommandEvent(NS_CONTENT_COMMAND_PASTE);
++        case GDK_Redo:
++            return DispatchContentCommandEvent(NS_CONTENT_COMMAND_REDO);
++        case GDK_Undo:
++        case GDK_F14:
++            return DispatchContentCommandEvent(NS_CONTENT_COMMAND_UNDO);
+     }
+-#endif /* ! AIX */
+-#endif /* MOZ_X11 */
+ 
+     nsKeyEvent event(PR_TRUE, NS_KEY_PRESS, this);
+     InitKeyEvent(event, aEvent);
+diff --git a/widget/src/gtk2/nsGtkKeyUtils.cpp b/widget/src/gtk2/nsGtkKeyUtils.cpp
+--- a/widget/src/gtk2/nsGtkKeyUtils.cpp
++++ b/widget/src/gtk2/nsGtkKeyUtils.cpp
+@@ -178,14 +178,11 @@
+     { NS_VK_EQUALS, GDK_plus }
+ };
+ 
+-#ifdef SOLARIS
+ // map Sun Keyboard special keysyms on to NS_VK keys
+ struct nsKeyConverter nsSunKeycodes[] = {
+-    {NS_VK_F1, GDK_Help }, //Mapping Help key to F1
+     {NS_VK_F11, 0x1005ff10 }, //Sun F11 key generates SunF36(0x1005ff10) keysym
+     {NS_VK_F12, 0x1005ff11 }  //Sun F12 key generates SunF37(0x1005ff11) keysym
+ };
+-#endif
+ 
+ int
+ GdkKeyCodeToDOMKeyCode(int aKeysym)
+@@ -211,14 +208,11 @@
+     if (aKeysym >= GDK_KP_0 && aKeysym <= GDK_KP_9)
+         return aKeysym - GDK_KP_0 + NS_VK_NUMPAD0;
+ 
+-#ifdef SOLARIS
+     // map Sun Keyboard special keysyms
+     for (i = 0; i < NS_ARRAY_LENGTH(nsSunKeycodes); i++) {
+         if (nsSunKeycodes[i].keysym == aKeysym)
+             return(nsSunKeycodes[i].vkCode);
+     }
+-#endif /* SOLARIS */
+-
+     // misc other things
+     for (i = 0; i < NS_ARRAY_LENGTH(nsKeycodes); i++) {
+         if (nsKeycodes[i].keysym == aKeysym)
--- a/patches/yelp-03-using-firefox4-gecko.diff	Mon Aug 15 01:46:22 2011 +0000
+++ b/patches/yelp-03-using-firefox4-gecko.diff	Mon Aug 15 02:22:00 2011 +0000
@@ -36,7 +36,7 @@
  version = "1.8.1";
  #else
 -if (strncmp (MOZILLA_VERSION, "1.9", strlen ("1.9")) == 0) {
-+if ((strncmp (MOZILLA_VERSION, "2.0", strlen ("2.0")) == 0) || (strncmp (MOZILLA_VERSION, "5.0", strlen ("5.0")) == 0)) {
++if ((strncmp (MOZILLA_VERSION, "2.0", strlen ("2.0")) == 0) || (strncmp (MOZILLA_VERSION, "5.0", strlen ("5.0")) == 0) || (strncmp (MOZILLA_VERSION, "6.0", strlen ("6.0")) == 0)) {
 +	version = "2.0";
 +} else if (strncmp (MOZILLA_VERSION, "1.9", strlen ("1.9")) == 0) {
  	version = "1.9";
--- a/specs/SUNWfirefox.spec	Mon Aug 15 01:46:22 2011 +0000
+++ b/specs/SUNWfirefox.spec	Mon Aug 15 02:22:00 2011 +0000
@@ -199,10 +199,10 @@
 %dir %attr (0755, root, other) %{_libdir}/pkgconfig
 %{_libdir}/pkgconfig/*
 %{_libdir}/firefox/xpidl
-%{_libdir}/firefox/xpt_dump
-%{_libdir}/firefox/xpt_link
 
 %changelog
+* Fri Aug 12 2011 - [email protected]
+- Update to Firefox 6.0.
 * Tue Jul 26 2011 - [email protected]
 - Fix CR 7071032.
 * Tue Jul 12 2011 - [email protected]