Bug 471346 - Port GetDefaultFeedReader to SeaMonkey shell service, r=Standard8, Callek, IanN
authorFrank Wein <mcsmurf@mcsmurf.de>
Wed, 15 Apr 2009 15:05:51 +0200
changeset 5754 141ea4d58ba85365748ef0d843f2923c6a87f404
parent 5753 71e60f59c680d061300584ec9a37784348d76731
child 5755 10b98b849f7c5cac328cf6b8ce076576b2a03e77
push idunknown
push userunknown
push dateunknown
reviewersStandard8, Callek, IanN
bugs471346
Bug 471346 - Port GetDefaultFeedReader to SeaMonkey shell service, r=Standard8, Callek, IanN
suite/Makefile.in
suite/app/Makefile.in
suite/build/Makefile.in
suite/build/nsSuiteModule.cpp
suite/feeds/src/FeedConverter.js
suite/shell/public/nsIShellService.idl
suite/shell/src/Makefile.in
suite/shell/src/nsGNOMEShellService.cpp
suite/shell/src/nsGNOMEShellService.h
suite/shell/src/nsMacShellService.cpp
suite/shell/src/nsMacShellService.h
suite/shell/src/nsWindowsShellService.cpp
suite/shell/src/nsWindowsShellService.h
--- a/suite/Makefile.in
+++ b/suite/Makefile.in
@@ -56,21 +56,21 @@ PARALLEL_DIRS	+= \
 		feeds/src \
 		locales \
 		modules \
 		themes/classic \
 		themes/modern \
 		profile \
 		security \
 		shell/public \
+		shell/src \
 		smile \
 		$(NULL)
 
 ifeq ($(OS_ARCH),WINNT)
-PARALLEL_DIRS += shell/src
 ifdef MOZ_INSTALLER
 PARALLEL_DIRS += installer/windows
 endif
 endif
 
 ifdef MOZ_MAIL_NEWS
 PARALLEL_DIRS += mailnews
 endif
--- a/suite/app/Makefile.in
+++ b/suite/app/Makefile.in
@@ -152,17 +152,17 @@ NSDISTMODE = copy
 include $(topsrcdir)/config/config.mk
 
 ifdef _MSC_VER
 WIN32_EXE_LDFLAGS += -ENTRY:wmainCRTStartup
 endif
 
 ifdef BUILD_STATIC_LIBS
 
-ifeq ($(OS_ARCH),WINNT)
+ifneq (,$(filter windows cocoa gtk2, $(MOZ_WIDGET_TOOLKIT)))
 LIBS += ../shell/src/$(LIB_PREFIX)shellservice_s.$(LIB_SUFFIX)
 endif
 
 include $(topsrcdir)/config/static-config.mk
 
 EXTRA_DEPS	+= \
 	$(STATIC_EXTRA_DEPS) \
 	$(NULL)
--- a/suite/build/Makefile.in
+++ b/suite/build/Makefile.in
@@ -87,40 +87,41 @@ LOCAL_INCLUDES += \
 
 SHARED_LIBRARY_LIBS = \
 	../profile/$(LIB_PREFIX)suiteprofile_s.$(LIB_SUFFIX) \
 	../profile/migration/src/$(LIB_PREFIX)suitemigration_s.$(LIB_SUFFIX) \
 	../browser/src/$(LIB_PREFIX)suitebrowser_s.$(LIB_SUFFIX) \
 	../feeds/src/$(LIB_PREFIX)suitefeeds_s.$(LIB_SUFFIX) \
 	$(NULL)
 
+# We need to link the windows shell service into seamonkey.exe.
+ifdef BUILD_STATIC_LIBS
+BUILD_STATIC_SHELL = 1
+DEFINES += -DBUILD_STATIC_SHELL=1
+endif
+
+ifndef BUILD_STATIC_SHELL
+ifneq (,$(filter windows cocoa gtk2, $(MOZ_WIDGET_TOOLKIT)))
+SHARED_LIBRARY_LIBS += ../shell/src/$(LIB_PREFIX)shellservice_s.$(LIB_SUFFIX)
+ifeq (,$(MOZ_ENABLE_LIBXUL))
+EXTRA_DSO_LIBS += thebes
+endif
+endif
+endif
+
 EXTRA_DSO_LDOPTS += \
 	$(LIBS_DIR) \
 	$(EXTRA_DSO_LIBS) \
 	$(call EXPAND_LIBNAME_PATH,unicharutil_external_s,$(LIBXUL_DIST)/lib) \
 	$(LIBXUL_DIST)/../modules/libreg/src/$(LIB_PREFIX)mozreg_s.$(LIB_SUFFIX) \
 	$(MOZ_JS_LIBS) \
 	$(XPCOM_GLUE_LDOPTS) \
 	$(MOZ_COMPONENT_LIBS) \
 	$(NULL)
 
-# We need to link the windows shell service into seamonkey.exe.
-ifdef BUILD_STATIC_LIBS
-BUILD_STATIC_SHELL = 1
-DEFINES += -DBUILD_STATIC_SHELL=1
-endif
-
-ifndef BUILD_STATIC_SHELL
-ifeq ($(OS_ARCH),WINNT)
-SHARED_LIBRARY_LIBS += ../shell/src/$(LIB_PREFIX)shellservice_s.$(LIB_SUFFIX)
-ifeq (,$(MOZ_ENABLE_LIBXUL))
-EXTRA_DSO_LDOPTS += $(LIBXUL_DIST)/lib/$(LIB_PREFIX)thebes.$(LIB_SUFFIX)
-endif
-endif
-endif
 
 # Mac: Need to link with CoreFoundation for Mac Migrators (PList reading code)
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 EXTRA_DSO_LDOPTS += \
 	$(TK_LIBS) \
 	$(NULL)
 endif
 
--- a/suite/build/nsSuiteModule.cpp
+++ b/suite/build/nsSuiteModule.cpp
@@ -48,26 +48,38 @@
 #include "nsBookmarksService.h"
 #include "nsFeedSniffer.h"
 
 #if defined(XP_WIN)
 #include "nsUrlWidget.h"
 #if !defined(BUILD_STATIC_SHELL)
 #include "nsWindowsShellService.h"
 #endif
+#elif defined(XP_MACOSX)
+#include "nsMacShellService.h"
+#elif defined(MOZ_WIDGET_GTK2)
+#include "nsGNOMEShellService.h"
 #endif
 
 /////////////////////////////////////////////////////////////////////////////
 
 #if defined(XP_WIN)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsUrlWidget, Init)
 #if !defined(BUILD_STATIC_SHELL)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsWindowsShellService, Init)
 #endif
-#endif // Windows
+#elif defined(XP_MACOSX)
+#if !defined(BUILD_STATIC_SHELL)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacShellService)
+#endif
+#elif defined(MOZ_WIDGET_GTK2)
+#if !defined(BUILD_STATIC_SHELL)
+NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGNOMEShellService, Init)
+#endif
+#endif
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSuiteDirectoryProvider)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsProfileMigrator)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSeamonkeyProfileMigrator)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsThunderbirdProfileMigrator)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(LocalSearchDataSource, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(InternetSearchDataSource, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsBookmarksService, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsFeedSniffer)
@@ -78,18 +90,32 @@ static const nsModuleComponentInfo compo
 #ifdef XP_WIN
   { NS_IURLWIDGET_CLASSNAME, NS_IURLWIDGET_CID,
     NS_IURLWIDGET_CONTRACTID, nsUrlWidgetConstructor },
 #if !defined(BUILD_STATIC_SHELL)
   { "SeaMonkey Windows Integration",
     NS_SUITEWININTEGRATION_CID,
     NS_SUITEWININTEGRATION_CONTRACTID,
     nsWindowsShellServiceConstructor },
+  { "SeaMonkey Windows Feed Integration",
+    NS_SUITEWINFEED_CID,
+    NS_SUITEWINFEED_CONTRACTID,
+    nsWindowsShellServiceConstructor },
 #endif
-#endif // XP_WIN
+#elif defined(XP_MACOSX) && !defined(BUILD_STATIC_SHELL)
+  { "SeaMonkey Mac Feed Integration",
+    NS_SUITEMACFEED_CID,
+    NS_SUITEMACFEED_CONTRACTID,
+    nsMacShellServiceConstructor },
+#elif defined(MOZ_WIDGET_GTK2) && !defined(BUILD_STATIC_SHELL)
+  { "SeaMonkey Linux Feed Integration",
+    NS_SUITEGNOMEFEED_CID,
+    NS_SUITEGNOMEFEED_CONTRACTID,
+    nsGNOMEShellServiceConstructor },
+#endif
 
   { "nsSuiteDirectoryProvider",
     NS_SUITEDIRECTORYPROVIDER_CID,
     NS_SUITEDIRECTORYPROVIDER_CONTRACTID,
     nsSuiteDirectoryProviderConstructor,
     nsSuiteDirectoryProvider::Register,
     nsSuiteDirectoryProvider::Unregister },
 
--- a/suite/feeds/src/FeedConverter.js
+++ b/suite/feeds/src/FeedConverter.js
@@ -446,17 +446,17 @@ FeedResultService.prototype = {
         spec = feedURI.spec;
       }
       else
         spec = "feed:" + spec;
 
       // Retrieving the shell service might fail on some systems, most
       // notably systems where GNOME is not installed.
       try {
-        var ss = Components.classes["@mozilla.org/suite/shell-service;1"]
+        var ss = Components.classes["@mozilla.org/suite/shell-feed-service;1"]
                            .getService(Components.interfaces.nsIShellService);
         ss.openApplicationWithURI(clientApp, spec);
       } catch(e) {
         // If we couldn't use the shell service, fallback to using a
         // nsIProcess instance
         var p = Components.classes["@mozilla.org/process/util;1"]
                           .createInstance(Components.interfaces.nsIProcess);
         p.init(clientApp);
--- a/suite/shell/public/nsIShellService.idl
+++ b/suite/shell/public/nsIShellService.idl
@@ -35,18 +35,19 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 
 #include "nsISupports.idl"
 
 interface nsIDOMElement;
+interface nsILocalFile;
 
-[scriptable, uuid(58E4B6D9-10CB-4DA0-AF44-E47C62365380)]
+[scriptable, uuid(BEBB8B6A-8AF4-4CF2-85AC-022F7C6A87A9)]
 interface nsIShellService : nsISupports
 {
   /**
    * app types we can be registered to handle
    */
   const unsigned short BROWSER = 0x0001;
   const unsigned short MAIL    = 0x0002;
   const unsigned short NEWS    = 0x0004;
@@ -115,9 +116,24 @@ interface nsIShellService : nsISupports
   const long BACKGROUND_CENTER    = 3;
 
   /**
    * The desktop background color, visible when no background image is
    * used, or if the background image is centered and does not fill the
    * entire screen. An RGB value (r << 16 | g << 8 | b)
    */
   attribute unsigned long desktopBackgroundColor;
+
+  /**
+   * Opens an application with a specific URI to load.
+   * @param   application
+   *          The application file (or bundle directory, on OS X)
+   * @param   uri
+   *          The uri to be loaded by the application
+   */
+  void openApplicationWithURI(in nsILocalFile aApplication, in ACString aURI);
+
+  /**
+   * The default system handler for web feeds
+   */
+  readonly attribute nsILocalFile defaultFeedReader;
 };
+
--- a/suite/shell/src/Makefile.in
+++ b/suite/shell/src/Makefile.in
@@ -24,16 +24,28 @@ REQUIRES = \
 	layout \
 	$(NULL)
 
 ifeq ($(OS_ARCH),WINNT)
 CPPSRCS = nsWindowsShellService.cpp
 OS_LIBS         += $(call EXPAND_LIBNAME,ole32 version uuid shell32)
 
 EXTRA_COMPONENTS = nsSetDefault.js
+else
+ifeq ($(MOZ_WIDGET_TOOLKIT), cocoa)
+CPPSRCS = nsMacShellService.cpp
+else
+ifeq ($(MOZ_WIDGET_TOOLKIT), gtk2)
+CPPSRCS = nsGNOMEShellService.cpp
+REQUIRES	+= \
+		mozgnome \
+		thebes \
+		$(NULL)
+endif
+endif
 endif
 
 # We need to link the windows shell service into seamonkey.exe.
 # DEFINES needs to be set before config.mk is included,
 # because app-config.mk is loaded after config.mk reads DEFINES.
 ifdef BUILD_STATIC_LIBS
 BUILD_STATIC_SHELL = 1
 DEFINES += -DBUILD_STATIC_SHELL=1
@@ -48,9 +60,11 @@ IS_COMPONENT = 1
 MODULE_NAME = nsSuiteShellModule
 endif
 endif
 
 ifdef MOZ_MAIL_NEWS
 DEFINES += -DMOZ_MAIL_NEWS
 endif
 
+DEFINES += -DMOZ_APP_NAME=\"$(MOZ_APP_NAME)\"
+
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/suite/shell/src/nsGNOMEShellService.cpp
@@ -0,0 +1,175 @@
+/* -*- Mode: C++; tab-width: 2; 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 Shell Service.
+ *
+ * The Initial Developer of the Original Code is mozilla.org.
+ * Portions created by the Initial Developer are Copyright (C) 2004
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsCOMPtr.h"
+#include "nsComponentManagerUtils.h"
+#include "nsDirectoryServiceDefs.h"
+#include "nsDirectoryServiceUtils.h"
+#include "nsGNOMEShellService.h"
+#include "nsServiceManagerUtils.h"
+#include "nsIGConfService.h"
+#include "nsIGenericFactory.h"
+#include "nsIGnomeVFSService.h"
+#include "nsILocalFile.h"
+#include "nsIProcess.h"
+#include "prenv.h"
+
+NS_IMPL_ISUPPORTS1(nsGNOMEShellService, nsIShellService)
+
+nsresult
+nsGNOMEShellService::Init()
+{
+  nsresult rv;
+
+  // GConf and GnomeVFS _must_ be available, or we do not allow
+  // CreateInstance to succeed.
+
+  nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
+  nsCOMPtr<nsIGnomeVFSService> vfs =
+    do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
+
+  if (!gconf || !vfs)
+    return NS_ERROR_NOT_AVAILABLE;
+
+  // Check G_BROKEN_FILENAMES.  If it's set, then filenames in glib use
+  // the locale encoding.  If it's not set, they use UTF-8.
+  mUseLocaleFilenames = PR_GetEnv("G_BROKEN_FILENAMES") != nsnull;
+
+  nsCOMPtr<nsIFile> appPath;
+  rv = NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR,
+                              getter_AddRefs(appPath));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = appPath->AppendNative(NS_LITERAL_CSTRING(MOZ_APP_NAME));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return appPath->GetNativePath(mAppPath);
+}
+
+NS_IMETHODIMP
+nsGNOMEShellService::IsDefaultClient(PRBool aStartupCheck, PRUint16 aApps,
+                                     PRBool* aIsDefaultClient)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsGNOMEShellService::SetDefaultClient(PRBool aForAllUsers,
+                                      PRBool aClaimAllTypes, PRUint16 aApps)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsGNOMEShellService::GetShouldCheckDefaultClient(PRBool* aResult)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsGNOMEShellService::SetShouldCheckDefaultClient(PRBool aShouldCheck)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsGNOMEShellService::GetShouldBeDefaultClientFor(PRUint16* aApps)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsGNOMEShellService::SetShouldBeDefaultClientFor(PRUint16 aApps)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsGNOMEShellService::SetDesktopBackground(nsIDOMElement* aElement, 
+                                          PRInt32 aPosition)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsGNOMEShellService::GetDesktopBackgroundColor(PRUint32 *aColor)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsGNOMEShellService::SetDesktopBackgroundColor(PRUint32 aColor)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsGNOMEShellService::OpenApplicationWithURI(nsILocalFile* aApplication, const nsACString& aURI)
+{
+  nsresult rv;
+  nsCOMPtr<nsIProcess> process = 
+    do_CreateInstance("@mozilla.org/process/util;1", &rv);
+  if (NS_FAILED(rv))
+    return rv;
+  
+  rv = process->Init(aApplication);
+  if (NS_FAILED(rv))
+    return rv;
+
+  const nsCString& spec = PromiseFlatCString(aURI);
+  const char* specStr = spec.get();
+  return process->Run(PR_FALSE, &specStr, 1);
+}
+
+NS_IMETHODIMP
+nsGNOMEShellService::GetDefaultFeedReader(nsILocalFile** _retval)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+#ifdef BUILD_STATIC_SHELL
+NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGNOMEShellService, Init)
+
+static const nsModuleComponentInfo components[] = {
+  { "SeaMonkey Linux Feed Integration",
+    NS_SUITEGNOMEFEED_CID,
+    NS_SUITEGNOMEFEED_CONTRACTID,
+    nsGNOMEShellServiceConstructor },
+};
+
+NS_IMPL_NSGETMODULE(nsSuiteShellModule, components)
+#endif
+
new file mode 100644
--- /dev/null
+++ b/suite/shell/src/nsGNOMEShellService.h
@@ -0,0 +1,74 @@
+/* -*- Mode: C++; tab-width: 2; 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 Shell Service.
+ *
+ * The Initial Developer of the Original Code is mozilla.org.
+ * Portions created by the Initial Developer are Copyright (C) 2004
+ * 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 nsgnomeshellservice_h____
+#define nsgnomeshellservice_h____
+
+#include "nsIShellService.h"
+
+
+#include "nsStringGlue.h"
+
+/* This is temporary until nsGNOMEShellService implements all functions of
+   nsIShellService. Then this can be replaced with
+   "@mozilla.org/suite/shell-service;1" */
+#define NS_SUITEGNOMEFEED_CONTRACTID "@mozilla.org/suite/shell-feed-service;1"
+
+#define NS_SUITEGNOMEFEED_CID \
+{0xc16cfa25, 0xa74a, 0x420b, {0xa5, 0x45, 0x4b, 0xc0, 0x6b, 0x08, 0xa8, 0x65}}
+
+struct ProtocolAssociation;
+
+class nsGNOMEShellService : public nsIShellService
+{
+public:
+  nsGNOMEShellService() : mCheckedThisSessionClient(PR_FALSE) { }
+
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSISHELLSERVICE
+
+  nsresult Init() NS_HIDDEN;
+
+private:
+  ~nsGNOMEShellService() {}
+
+  nsCString mAppPath;
+  PRPackedBool mUseLocaleFilenames;
+  PRPackedBool mCheckedThisSessionClient;
+};
+
+#endif // nsgnomeshellservice_h____
+
new file mode 100644
--- /dev/null
+++ b/suite/shell/src/nsMacShellService.cpp
@@ -0,0 +1,205 @@
+/* -*- Mode: C++; tab-width: 2; 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 Shell Service.
+ *
+ * The Initial Developer of the Original Code is Ben Goodger.
+ * Portions created by the Initial Developer are Copyright (C) 2004
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ben Goodger <ben@mozilla.org> (Original Author)
+ *   Asaf Romano <mozilla.mano@sent.com>
+ *   Benjamin Smedberg <benjamin@smedbergs.us>
+ *
+ * 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 "nsServiceManagerUtils.h"
+#include "nsComponentManagerUtils.h"
+#include "nsMacShellService.h"
+#include "nsStringGlue.h"
+#include "nsIDOMElement.h"
+#include "nsILocalFileMac.h"
+#include "nsIGenericFactory.h"
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Carbon/Carbon.h>
+
+#define SAFARI_BUNDLE_IDENTIFIER "com.apple.Safari"
+
+NS_IMPL_ISUPPORTS1(nsMacShellService, nsIShellService)
+
+NS_IMETHODIMP
+nsMacShellService::IsDefaultClient(PRBool aStartupCheck, PRUint16 aApps, PRBool *aIsDefaultClient)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsMacShellService::SetDefaultClient(PRBool aForAllUsers,
+                                    PRBool aClaimAllTypes, PRUint16 aApps)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsMacShellService::GetShouldCheckDefaultClient(PRBool* aResult)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsMacShellService::SetShouldCheckDefaultClient(PRBool aShouldCheck)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsMacShellService::GetShouldBeDefaultClientFor(PRUint16* aApps)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsMacShellService::SetShouldBeDefaultClientFor(PRUint16 aApps)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsMacShellService::SetDesktopBackground(nsIDOMElement* aElement,
+                                            PRInt32 aPosition)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsMacShellService::GetDesktopBackgroundColor(PRUint32 *aColor)
+{
+  // This method and |SetDesktopBackgroundColor| has no meaning on Mac OS X.
+  // The mac desktop preferences UI uses pictures for the few solid colors it
+  // supports.
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsMacShellService::SetDesktopBackgroundColor(PRUint32 aColor)
+{
+  // This method and |GetDesktopBackgroundColor| has no meaning on Mac OS X.
+  // The mac desktop preferences UI uses pictures for the few solid colors it
+  // supports.
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsMacShellService::OpenApplicationWithURI(nsILocalFile* aApplication, const nsACString& aURI)
+{
+  nsCOMPtr<nsILocalFileMac> lfm(do_QueryInterface(aApplication));
+  CFURLRef appURL;
+  nsresult rv = lfm->GetCFURL(&appURL);
+  if (NS_FAILED(rv))
+    return rv;
+  
+  const nsCString& spec = PromiseFlatCString(aURI);
+  const UInt8* uriString = (const UInt8*)spec.get();
+  CFURLRef uri = ::CFURLCreateWithBytes(NULL, uriString, aURI.Length(),
+                                        kCFStringEncodingUTF8, NULL);
+  if (!uri) 
+    return NS_ERROR_OUT_OF_MEMORY;
+  
+  CFArrayRef uris = ::CFArrayCreate(NULL, (const void**)&uri, 1, NULL);
+  if (!uris) {
+    ::CFRelease(uri);
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+  
+  LSLaunchURLSpec launchSpec;
+  launchSpec.appURL = appURL;
+  launchSpec.itemURLs = uris;
+  launchSpec.passThruParams = NULL;
+  launchSpec.launchFlags = kLSLaunchDefaults;
+  launchSpec.asyncRefCon = NULL;
+  
+  OSErr err = ::LSOpenFromURLSpec(&launchSpec, NULL);
+  
+  ::CFRelease(uris);
+  ::CFRelease(uri);
+  
+  return err != noErr ? NS_ERROR_FAILURE : NS_OK;
+}
+
+NS_IMETHODIMP
+nsMacShellService::GetDefaultFeedReader(nsILocalFile** _retval)
+{
+  nsresult rv = NS_ERROR_FAILURE;
+  *_retval = nsnull;
+
+  CFStringRef defaultHandlerID = ::LSCopyDefaultHandlerForURLScheme(CFSTR("feed"));
+  if (!defaultHandlerID) {
+    defaultHandlerID = ::CFStringCreateWithCString(kCFAllocatorDefault,
+                                                   SAFARI_BUNDLE_IDENTIFIER,
+                                                   kCFStringEncodingASCII);
+  }
+
+  CFURLRef defaultHandlerURL = NULL;
+  OSStatus status = ::LSFindApplicationForInfo(kLSUnknownCreator,
+                                               defaultHandlerID,
+                                               NULL, // inName
+                                               NULL, // outAppRef
+                                               &defaultHandlerURL);
+
+  if (status == noErr && defaultHandlerURL) {
+    nsCOMPtr<nsILocalFileMac> defaultReader =
+      do_CreateInstance("@mozilla.org/file/local;1", &rv);
+    if (NS_SUCCEEDED(rv)) {
+      rv = defaultReader->InitWithCFURL(defaultHandlerURL);
+      if (NS_SUCCEEDED(rv)) {
+        NS_ADDREF(*_retval = defaultReader);
+      }
+    }
+
+    ::CFRelease(defaultHandlerURL);
+  }
+
+  ::CFRelease(defaultHandlerID);
+
+  return rv;
+}
+
+#ifdef BUILD_STATIC_SHELL
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacShellService)
+
+static const nsModuleComponentInfo components[] = {
+  { "SeaMonkey Mac Feed Integration",
+    NS_SUITEMACFEED_CID,
+    NS_SUITEMACFEED_CONTRACTID,
+    nsMacShellServiceConstructor },
+};
+
+NS_IMPL_NSGETMODULE(nsSuiteShellModule, components)
+#endif
+
new file mode 100644
--- /dev/null
+++ b/suite/shell/src/nsMacShellService.h
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 2; 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 Shell Service.
+ *
+ * The Initial Developer of the Original Code is mozilla.org.
+ * Portions created by the Initial Developer are Copyright (C) 2004
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Ben Goodger    <ben@mozilla.org>
+ *
+ * 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 nsmacshellservice_h____
+#define nsmacshellservice_h____
+
+#include "nsIShellService.h"
+
+/* This is temporary until nsMacShellService implements all functions of
+   nsIShellService. Then this can be replaced with
+   "@mozilla.org/suite/shell-service;1" */
+#define NS_SUITEMACFEED_CONTRACTID "@mozilla.org/suite/shell-feed-service;1"
+
+#define NS_SUITEMACFEED_CID \
+{0xac17e6f0, 0x50c9, 0x4901, {0xab, 0x08, 0xf8, 0x70, 0xbf, 0xcd, 0x12, 0xce}}
+
+class nsMacShellService : public nsIShellService
+{
+public:
+  nsMacShellService() : mCheckedThisSessionClient(PR_FALSE) {};
+  virtual ~nsMacShellService() {};
+
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSISHELLSERVICE
+
+private:
+  PRPackedBool mCheckedThisSessionClient;
+};
+
+#endif
--- a/suite/shell/src/nsWindowsShellService.cpp
+++ b/suite/shell/src/nsWindowsShellService.cpp
@@ -56,17 +56,16 @@
 #include "nsNativeCharsetUtils.h"
 #include "nsUnicharUtils.h"
 #include "nsIStringBundle.h"
 #include "nsIServiceManager.h"
 #include "nsServiceManagerUtils.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsDirectoryServiceUtils.h"
-#include "nsCOMPtr.h"
 #include <mbstring.h>
 #include "nsIGenericFactory.h"
 
 #ifdef MOZILLA_INTERNAL_API
 #define CaseInsensitiveCompare nsCaseInsensitiveStringComparator()
 #endif
 
 #ifdef _WIN32_WINNT
@@ -788,26 +787,103 @@ nsWindowsShellService::SetDesktopBackgro
   if (REG_SUCCEEDED(rv)) {
     char rgb[12];
     sprintf((char*)rgb, "%u %u %u\0", r, g, b);
     NS_ConvertUTF8toUTF16 backColor(rgb);
     ::RegSetValueExW(key, L"Background",
                      0, REG_SZ, (const BYTE *)backColor.get(),
                      (backColor.Length() + 1) * sizeof(PRUnichar));
   }
-  
+
   // Close the key we opened.
   ::RegCloseKey(key);
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsWindowsShellService::OpenApplicationWithURI(nsILocalFile* aApplication,
+                                              const nsACString& aURI)
+{
+  nsresult rv;
+  nsCOMPtr<nsIProcess> process = 
+    do_CreateInstance("@mozilla.org/process/util;1", &rv);
+  if (NS_FAILED(rv))
+    return rv;
+  
+  rv = process->Init(aApplication);
+  if (NS_FAILED(rv))
+    return rv;
+  
+  const nsCString& spec = PromiseFlatCString(aURI);
+  const char* specStr = spec.get();
+  return process->Run(PR_FALSE, &specStr, 1);
+}
+
+NS_IMETHODIMP
+nsWindowsShellService::GetDefaultFeedReader(nsILocalFile** _retval)
+{
+  *_retval = nsnull;
+
+  HKEY theKey;
+  nsresult rv = OpenKeyForReading(HKEY_CLASSES_ROOT, 
+                                  L"feed\\shell\\open\\command",
+                                  &theKey);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  DWORD buf;
+  LONG res = ::RegQueryValueExW(theKey, NULL, NULL, NULL, NULL, &buf);
+
+  if (REG_FAILED(res))
+    return NS_ERROR_FAILURE;
+
+  // Buffer size must be a multiple of 2
+  NS_ENSURE_STATE(buf % 2 == 0);
+  nsAutoString path;
+  path.SetLength(buf / 2 - 1);
+  res = ::RegQueryValueExW(theKey, NULL, NULL, NULL, (LPBYTE)path.BeginWriting(), &buf);
+  ::RegCloseKey(theKey);
+  if (REG_FAILED(res))
+    return NS_ERROR_FAILURE;
+
+  if (path.IsEmpty())
+    return NS_ERROR_FAILURE;
+
+  if (path.First() == '"') {
+    // Everything inside the quotes
+    path = Substring(path, 1, path.FindChar('"', 1) - 1);
+  } else {
+    // Everything up to the first space
+    path = Substring(path, 0, path.FindChar(' '));
+  }
+
+  nsCOMPtr<nsILocalFile> defaultReader =
+    do_CreateInstance("@mozilla.org/file/local;1", &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = defaultReader->InitWithPath(path);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  PRBool exists;
+  rv = defaultReader->Exists(&exists);
+  NS_ENSURE_SUCCESS(rv, rv);
+  if (!exists)
+    return NS_ERROR_FAILURE;
+
+  NS_ADDREF(*_retval = defaultReader);
+  return NS_OK;
+}
+
 #ifdef BUILD_STATIC_SHELL
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsWindowsShellService, Init)
 
 static const nsModuleComponentInfo components[] = {
   { "SeaMonkey Windows Integration",
     NS_SUITEWININTEGRATION_CID,
     NS_SUITEWININTEGRATION_CONTRACTID,
     nsWindowsShellServiceConstructor },
+  { "SeaMonkey Windows Feed Integration",
+    NS_SUITEWINFEED_CID,
+    NS_SUITEWINFEED_CONTRACTID,
+    nsWindowsShellServiceConstructor },
 };
 
 NS_IMPL_NSGETMODULE(nsSuiteShellModule, components)
 #endif
--- a/suite/shell/src/nsWindowsShellService.h
+++ b/suite/shell/src/nsWindowsShellService.h
@@ -43,16 +43,21 @@
 
 #include <windows.h>
 
 #define NS_SUITEWININTEGRATION_CONTRACTID "@mozilla.org/suite/shell-service;1"
 
 #define NS_SUITEWININTEGRATION_CID \
 {0x39b688ec, 0xe308, 0x49e5, {0xbe, 0x6b, 0x28, 0xdc, 0x7f, 0xcd, 0x61, 0x54}}
 
+#define NS_SUITEWINFEED_CONTRACTID "@mozilla.org/suite/shell-feed-service;1"
+
+#define NS_SUITEWINFEED_CID \
+{0xd5cbb2a1, 0xaa33, 0x478e, {0xa1, 0x2a, 0xd4, 0xb2, 0x2b, 0x4f, 0x19, 0xd8}}
+
 typedef struct {
   char* keyName;
   char* valueName;
   char* valueData;
 
   PRInt32 flags;
 } SETTING;