LCOV - code coverage report
Current view: top level - browser/components/shell - nsGNOMEShellService.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 302 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 18 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #include "mozilla/ArrayUtils.h"
       7             : 
       8             : #include "nsCOMPtr.h"
       9             : #include "nsGNOMEShellService.h"
      10             : #include "nsShellService.h"
      11             : #include "nsIServiceManager.h"
      12             : #include "nsIFile.h"
      13             : #include "nsIProperties.h"
      14             : #include "nsDirectoryServiceDefs.h"
      15             : #include "nsIPrefService.h"
      16             : #include "prenv.h"
      17             : #include "nsString.h"
      18             : #include "nsIGConfService.h"
      19             : #include "nsIGIOService.h"
      20             : #include "nsIGSettingsService.h"
      21             : #include "nsIStringBundle.h"
      22             : #include "nsIOutputStream.h"
      23             : #include "nsIProcess.h"
      24             : #include "nsServiceManagerUtils.h"
      25             : #include "nsComponentManagerUtils.h"
      26             : #include "nsIDOMHTMLImageElement.h"
      27             : #include "nsIImageLoadingContent.h"
      28             : #include "imgIRequest.h"
      29             : #include "imgIContainer.h"
      30             : #include "mozilla/Sprintf.h"
      31             : #if defined(MOZ_WIDGET_GTK)
      32             : #include "nsIImageToPixbuf.h"
      33             : #endif
      34             : #include "nsXULAppAPI.h"
      35             : #include "gfxPlatform.h"
      36             : 
      37             : #include <glib.h>
      38             : #include <glib-object.h>
      39             : #include <gtk/gtk.h>
      40             : #include <gdk/gdk.h>
      41             : #include <gdk-pixbuf/gdk-pixbuf.h>
      42             : #include <limits.h>
      43             : #include <stdlib.h>
      44             : 
      45             : using namespace mozilla;
      46             : 
      47             : struct ProtocolAssociation
      48             : {
      49             :   const char *name;
      50             :   bool essential;
      51             : };
      52             : 
      53             : struct MimeTypeAssociation
      54             : {
      55             :   const char *mimeType;
      56             :   const char *extensions;
      57             : };
      58             : 
      59             : static const ProtocolAssociation appProtocols[] = {
      60             :   { "http",   true     },
      61             :   { "https",  true     },
      62             :   { "ftp",    false },
      63             :   { "chrome", false }
      64             : };
      65             : 
      66             : static const MimeTypeAssociation appTypes[] = {
      67             :   { "text/html",             "htm html shtml" },
      68             :   { "application/xhtml+xml", "xhtml xht"      }
      69             : };
      70             : 
      71             : // GConf registry key constants
      72             : #define DG_BACKGROUND "/desktop/gnome/background"
      73             : 
      74             : #define kDesktopImageKey DG_BACKGROUND "/picture_filename"
      75             : #define kDesktopOptionsKey DG_BACKGROUND "/picture_options"
      76             : #define kDesktopDrawBGKey DG_BACKGROUND "/draw_background"
      77             : #define kDesktopColorKey DG_BACKGROUND "/primary_color"
      78             : 
      79             : #define kDesktopBGSchema "org.gnome.desktop.background"
      80             : #define kDesktopImageGSKey "picture-uri"
      81             : #define kDesktopOptionGSKey "picture-options"
      82             : #define kDesktopDrawBGGSKey "draw-background"
      83             : #define kDesktopColorGSKey "primary-color"
      84             : 
      85             : nsresult
      86           0 : nsGNOMEShellService::Init()
      87             : {
      88             :   nsresult rv;
      89             : 
      90           0 :   if (gfxPlatform::IsHeadless()) {
      91           0 :     return NS_ERROR_NOT_AVAILABLE;
      92             :   }
      93             : 
      94             :   // GConf, GSettings or GIO _must_ be available, or we do not allow
      95             :   // CreateInstance to succeed.
      96             : 
      97           0 :   nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
      98             :   nsCOMPtr<nsIGIOService> giovfs =
      99           0 :     do_GetService(NS_GIOSERVICE_CONTRACTID);
     100             :   nsCOMPtr<nsIGSettingsService> gsettings =
     101           0 :     do_GetService(NS_GSETTINGSSERVICE_CONTRACTID);
     102             : 
     103           0 :   if (!gconf && !giovfs && !gsettings)
     104           0 :     return NS_ERROR_NOT_AVAILABLE;
     105             : 
     106             :   // Check G_BROKEN_FILENAMES.  If it's set, then filenames in glib use
     107             :   // the locale encoding.  If it's not set, they use UTF-8.
     108           0 :   mUseLocaleFilenames = PR_GetEnv("G_BROKEN_FILENAMES") != nullptr;
     109             : 
     110           0 :   if (GetAppPathFromLauncher())
     111           0 :     return NS_OK;
     112             : 
     113             :   nsCOMPtr<nsIProperties> dirSvc
     114           0 :     (do_GetService("@mozilla.org/file/directory_service;1"));
     115           0 :   NS_ENSURE_TRUE(dirSvc, NS_ERROR_NOT_AVAILABLE);
     116             : 
     117           0 :   nsCOMPtr<nsIFile> appPath;
     118           0 :   rv = dirSvc->Get(XRE_EXECUTABLE_FILE, NS_GET_IID(nsIFile),
     119           0 :                    getter_AddRefs(appPath));
     120           0 :   NS_ENSURE_SUCCESS(rv, rv);
     121             : 
     122           0 :   return appPath->GetNativePath(mAppPath);
     123             : }
     124             : 
     125           0 : NS_IMPL_ISUPPORTS(nsGNOMEShellService, nsIGNOMEShellService, nsIShellService)
     126             : 
     127             : bool
     128           0 : nsGNOMEShellService::GetAppPathFromLauncher()
     129             : {
     130             :   gchar *tmp;
     131             : 
     132           0 :   const char *launcher = PR_GetEnv("MOZ_APP_LAUNCHER");
     133           0 :   if (!launcher)
     134           0 :     return false;
     135             : 
     136           0 :   if (g_path_is_absolute(launcher)) {
     137           0 :     mAppPath = launcher;
     138           0 :     tmp = g_path_get_basename(launcher);
     139           0 :     gchar *fullpath = g_find_program_in_path(tmp);
     140           0 :     if (fullpath && mAppPath.Equals(fullpath))
     141           0 :       mAppIsInPath = true;
     142           0 :     g_free(fullpath);
     143             :   } else {
     144           0 :     tmp = g_find_program_in_path(launcher);
     145           0 :     if (!tmp)
     146           0 :       return false;
     147           0 :     mAppPath = tmp;
     148           0 :     mAppIsInPath = true;
     149             :   }
     150             : 
     151           0 :   g_free(tmp);
     152           0 :   return true;
     153             : }
     154             : 
     155             : bool
     156           0 : nsGNOMEShellService::KeyMatchesAppName(const char *aKeyValue) const
     157             : {
     158             : 
     159             :   gchar *commandPath;
     160           0 :   if (mUseLocaleFilenames) {
     161             :     gchar *nativePath = g_filename_from_utf8(aKeyValue, -1,
     162           0 :                                              nullptr, nullptr, nullptr);
     163           0 :     if (!nativePath) {
     164           0 :       NS_ERROR("Error converting path to filesystem encoding");
     165           0 :       return false;
     166             :     }
     167             : 
     168           0 :     commandPath = g_find_program_in_path(nativePath);
     169           0 :     g_free(nativePath);
     170             :   } else {
     171           0 :     commandPath = g_find_program_in_path(aKeyValue);
     172             :   }
     173             : 
     174           0 :   if (!commandPath)
     175           0 :     return false;
     176             : 
     177           0 :   bool matches = mAppPath.Equals(commandPath);
     178           0 :   g_free(commandPath);
     179           0 :   return matches;
     180             : }
     181             : 
     182             : bool
     183           0 : nsGNOMEShellService::CheckHandlerMatchesAppName(const nsACString &handler) const
     184             : {
     185             :   gint argc;
     186             :   gchar **argv;
     187           0 :   nsAutoCString command(handler);
     188             : 
     189             :   // The string will be something of the form: [/path/to/]browser "%s"
     190             :   // We want to remove all of the parameters and get just the binary name.
     191             : 
     192           0 :   if (g_shell_parse_argv(command.get(), &argc, &argv, nullptr) && argc > 0) {
     193           0 :     command.Assign(argv[0]);
     194           0 :     g_strfreev(argv);
     195             :   }
     196             : 
     197           0 :   if (!KeyMatchesAppName(command.get()))
     198           0 :     return false; // the handler is set to another app
     199             : 
     200           0 :   return true;
     201             : }
     202             : 
     203             : NS_IMETHODIMP
     204           0 : nsGNOMEShellService::IsDefaultBrowser(bool aStartupCheck,
     205             :                                       bool aForAllTypes,
     206             :                                       bool* aIsDefaultBrowser)
     207             : {
     208           0 :   *aIsDefaultBrowser = false;
     209             : 
     210           0 :   nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
     211           0 :   nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID);
     212             : 
     213             :   bool enabled;
     214           0 :   nsAutoCString handler;
     215           0 :   nsCOMPtr<nsIGIOMimeApp> gioApp;
     216             : 
     217           0 :   for (unsigned int i = 0; i < ArrayLength(appProtocols); ++i) {
     218           0 :     if (!appProtocols[i].essential)
     219           0 :       continue;
     220             : 
     221           0 :     if (gconf) {
     222           0 :       handler.Truncate();
     223           0 :       gconf->GetAppForProtocol(nsDependentCString(appProtocols[i].name),
     224           0 :                                &enabled, handler);
     225             : 
     226           0 :       if (!CheckHandlerMatchesAppName(handler) || !enabled)
     227           0 :         return NS_OK; // the handler is disabled or set to another app
     228             :     }
     229             : 
     230           0 :     if (giovfs) {
     231           0 :       handler.Truncate();
     232           0 :       giovfs->GetAppForURIScheme(nsDependentCString(appProtocols[i].name),
     233           0 :                                  getter_AddRefs(gioApp));
     234           0 :       if (!gioApp)
     235           0 :         return NS_OK;
     236             : 
     237           0 :       gioApp->GetCommand(handler);
     238             : 
     239           0 :       if (!CheckHandlerMatchesAppName(handler))
     240           0 :         return NS_OK; // the handler is set to another app
     241             :     }
     242             :   }
     243             : 
     244           0 :   *aIsDefaultBrowser = true;
     245             : 
     246           0 :   return NS_OK;
     247             : }
     248             : 
     249             : NS_IMETHODIMP
     250           0 : nsGNOMEShellService::SetDefaultBrowser(bool aClaimAllTypes,
     251             :                                        bool aForAllUsers)
     252             : {
     253             : #ifdef DEBUG
     254           0 :   if (aForAllUsers)
     255           0 :     NS_WARNING("Setting the default browser for all users is not yet supported");
     256             : #endif
     257             : 
     258           0 :   nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
     259           0 :   nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID);
     260           0 :   if (gconf) {
     261           0 :     nsAutoCString appKeyValue;
     262           0 :     if (mAppIsInPath) {
     263             :       // mAppPath is in the users path, so use only the basename as the launcher
     264           0 :       gchar *tmp = g_path_get_basename(mAppPath.get());
     265           0 :       appKeyValue = tmp;
     266           0 :       g_free(tmp);
     267             :     } else {
     268           0 :       appKeyValue = mAppPath;
     269             :     }
     270             : 
     271           0 :     appKeyValue.AppendLiteral(" %s");
     272             : 
     273           0 :     for (unsigned int i = 0; i < ArrayLength(appProtocols); ++i) {
     274           0 :       if (appProtocols[i].essential || aClaimAllTypes) {
     275           0 :         gconf->SetAppForProtocol(nsDependentCString(appProtocols[i].name),
     276           0 :                                  appKeyValue);
     277             :       }
     278             :     }
     279             :   }
     280             : 
     281           0 :   if (giovfs) {
     282             :     nsresult rv;
     283             :     nsCOMPtr<nsIStringBundleService> bundleService =
     284           0 :       do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
     285           0 :     NS_ENSURE_SUCCESS(rv, rv);
     286             : 
     287           0 :     nsCOMPtr<nsIStringBundle> brandBundle;
     288           0 :     rv = bundleService->CreateBundle(BRAND_PROPERTIES, getter_AddRefs(brandBundle));
     289           0 :     NS_ENSURE_SUCCESS(rv, rv);
     290             : 
     291           0 :     nsString brandShortName;
     292           0 :     brandBundle->GetStringFromName(u"brandShortName",
     293           0 :                                    getter_Copies(brandShortName));
     294             : 
     295             :     // use brandShortName as the application id.
     296           0 :     NS_ConvertUTF16toUTF8 id(brandShortName);
     297           0 :     nsCOMPtr<nsIGIOMimeApp> appInfo;
     298           0 :     rv = giovfs->CreateAppFromCommand(mAppPath,
     299             :                                       id,
     300           0 :                                       getter_AddRefs(appInfo));
     301           0 :     NS_ENSURE_SUCCESS(rv, rv);
     302             : 
     303             :     // set handler for the protocols
     304           0 :     for (unsigned int i = 0; i < ArrayLength(appProtocols); ++i) {
     305           0 :       if (appProtocols[i].essential || aClaimAllTypes) {
     306           0 :         appInfo->SetAsDefaultForURIScheme(nsDependentCString(appProtocols[i].name));
     307             :       }
     308             :     }
     309             : 
     310             :     // set handler for .html and xhtml files and MIME types:
     311           0 :     if (aClaimAllTypes) {
     312             :       // Add mime types for html, xhtml extension and set app to just created appinfo.
     313           0 :       for (unsigned int i = 0; i < ArrayLength(appTypes); ++i) {
     314           0 :         appInfo->SetAsDefaultForMimeType(nsDependentCString(appTypes[i].mimeType));
     315           0 :         appInfo->SetAsDefaultForFileExtensions(nsDependentCString(appTypes[i].extensions));
     316             :       }
     317             :     }
     318             :   }
     319             : 
     320           0 :   nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
     321           0 :   if (prefs) {
     322           0 :     (void) prefs->SetBoolPref(PREF_CHECKDEFAULTBROWSER, true);
     323             :     // Reset the number of times the dialog should be shown
     324             :     // before it is silenced.
     325           0 :     (void) prefs->SetIntPref(PREF_DEFAULTBROWSERCHECKCOUNT, 0);
     326             :   }
     327             : 
     328           0 :   return NS_OK;
     329             : }
     330             : 
     331             : NS_IMETHODIMP
     332           0 : nsGNOMEShellService::GetCanSetDesktopBackground(bool* aResult)
     333             : {
     334             :   // setting desktop background is currently only supported
     335             :   // for Gnome or desktops using the same GSettings and GConf keys
     336           0 :   const char* gnomeSession = getenv("GNOME_DESKTOP_SESSION_ID");
     337           0 :   if (gnomeSession) {
     338           0 :     *aResult = true;
     339             :   } else {
     340           0 :     *aResult = false;
     341             :   }
     342             : 
     343           0 :   return NS_OK;
     344             : }
     345             : 
     346             : static nsresult
     347           0 : WriteImage(const nsCString& aPath, imgIContainer* aImage)
     348             : {
     349             : #if !defined(MOZ_WIDGET_GTK)
     350             :   return NS_ERROR_NOT_AVAILABLE;
     351             : #else
     352             :   nsCOMPtr<nsIImageToPixbuf> imgToPixbuf =
     353           0 :     do_GetService("@mozilla.org/widget/image-to-gdk-pixbuf;1");
     354           0 :   if (!imgToPixbuf)
     355           0 :       return NS_ERROR_NOT_AVAILABLE;
     356             : 
     357           0 :   GdkPixbuf* pixbuf = imgToPixbuf->ConvertImageToPixbuf(aImage);
     358           0 :   if (!pixbuf)
     359           0 :       return NS_ERROR_NOT_AVAILABLE;
     360             : 
     361           0 :   gboolean res = gdk_pixbuf_save(pixbuf, aPath.get(), "png", nullptr, nullptr);
     362             : 
     363           0 :   g_object_unref(pixbuf);
     364           0 :   return res ? NS_OK : NS_ERROR_FAILURE;
     365             : #endif
     366             : }
     367             : 
     368             : NS_IMETHODIMP
     369           0 : nsGNOMEShellService::SetDesktopBackground(nsIDOMElement* aElement,
     370             :                                           int32_t aPosition)
     371             : {
     372             :   nsresult rv;
     373           0 :   nsCOMPtr<nsIImageLoadingContent> imageContent = do_QueryInterface(aElement, &rv);
     374           0 :   if (!imageContent) return rv;
     375             : 
     376             :   // get the image container
     377           0 :   nsCOMPtr<imgIRequest> request;
     378           0 :   rv = imageContent->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
     379           0 :                                 getter_AddRefs(request));
     380           0 :   if (!request) return rv;
     381           0 :   nsCOMPtr<imgIContainer> container;
     382           0 :   rv = request->GetImage(getter_AddRefs(container));
     383           0 :   if (!container) return rv;
     384             : 
     385             :   // Set desktop wallpaper filling style
     386           0 :   nsAutoCString options;
     387           0 :   if (aPosition == BACKGROUND_TILE)
     388           0 :     options.AssignLiteral("wallpaper");
     389           0 :   else if (aPosition == BACKGROUND_STRETCH)
     390           0 :     options.AssignLiteral("stretched");
     391           0 :   else if (aPosition == BACKGROUND_FILL)
     392           0 :     options.AssignLiteral("zoom");
     393           0 :   else if (aPosition == BACKGROUND_FIT)
     394           0 :     options.AssignLiteral("scaled");
     395             :   else
     396           0 :     options.AssignLiteral("centered");
     397             : 
     398             :   // Write the background file to the home directory.
     399           0 :   nsAutoCString filePath(PR_GetEnv("HOME"));
     400             : 
     401             :   // get the product brand name from localized strings
     402           0 :   nsString brandName;
     403           0 :   nsCID bundleCID = NS_STRINGBUNDLESERVICE_CID;
     404           0 :   nsCOMPtr<nsIStringBundleService> bundleService(do_GetService(bundleCID));
     405           0 :   if (bundleService) {
     406           0 :     nsCOMPtr<nsIStringBundle> brandBundle;
     407           0 :     rv = bundleService->CreateBundle(BRAND_PROPERTIES,
     408           0 :                                      getter_AddRefs(brandBundle));
     409           0 :     if (NS_SUCCEEDED(rv) && brandBundle) {
     410           0 :       rv = brandBundle->GetStringFromName(u"brandShortName",
     411           0 :                                           getter_Copies(brandName));
     412           0 :       NS_ENSURE_SUCCESS(rv, rv);
     413             :     }
     414             :   }
     415             : 
     416             :   // build the file name
     417           0 :   filePath.Append('/');
     418           0 :   filePath.Append(NS_ConvertUTF16toUTF8(brandName));
     419           0 :   filePath.AppendLiteral("_wallpaper.png");
     420             : 
     421             :   // write the image to a file in the home dir
     422           0 :   rv = WriteImage(filePath, container);
     423           0 :   NS_ENSURE_SUCCESS(rv, rv);
     424             : 
     425             :   // Try GSettings first. If we don't have GSettings or the right schema, fall back
     426             :   // to using GConf instead. Note that if GSettings works ok, the changes get
     427             :   // mirrored to GConf by the gsettings->gconf bridge in gnome-settings-daemon
     428             :   nsCOMPtr<nsIGSettingsService> gsettings =
     429           0 :     do_GetService(NS_GSETTINGSSERVICE_CONTRACTID);
     430           0 :   if (gsettings) {
     431           0 :     nsCOMPtr<nsIGSettingsCollection> background_settings;
     432           0 :     gsettings->GetCollectionForSchema(
     433           0 :       NS_LITERAL_CSTRING(kDesktopBGSchema), getter_AddRefs(background_settings));
     434           0 :     if (background_settings) {
     435           0 :       gchar *file_uri = g_filename_to_uri(filePath.get(), nullptr, nullptr);
     436           0 :       if (!file_uri)
     437           0 :          return NS_ERROR_FAILURE;
     438             : 
     439           0 :       background_settings->SetString(NS_LITERAL_CSTRING(kDesktopOptionGSKey),
     440           0 :                                      options);
     441             : 
     442           0 :       background_settings->SetString(NS_LITERAL_CSTRING(kDesktopImageGSKey),
     443           0 :                                      nsDependentCString(file_uri));
     444           0 :       g_free(file_uri);
     445           0 :       background_settings->SetBoolean(NS_LITERAL_CSTRING(kDesktopDrawBGGSKey),
     446           0 :                                       true);
     447           0 :       return rv;
     448             :     }
     449             :   }
     450             : 
     451             :   // if the file was written successfully, set it as the system wallpaper
     452           0 :   nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
     453             : 
     454           0 :   if (gconf) {
     455           0 :     gconf->SetString(NS_LITERAL_CSTRING(kDesktopOptionsKey), options);
     456             : 
     457             :     // Set the image to an empty string first to force a refresh
     458             :     // (since we could be writing a new image on top of an existing
     459             :     // Firefox_wallpaper.png and nautilus doesn't monitor the file for changes)
     460           0 :     gconf->SetString(NS_LITERAL_CSTRING(kDesktopImageKey),
     461           0 :                      EmptyCString());
     462             : 
     463           0 :     gconf->SetString(NS_LITERAL_CSTRING(kDesktopImageKey), filePath);
     464           0 :     gconf->SetBool(NS_LITERAL_CSTRING(kDesktopDrawBGKey), true);
     465             :   }
     466             : 
     467           0 :   return rv;
     468             : }
     469             : 
     470             : #define COLOR_16_TO_8_BIT(_c) ((_c) >> 8)
     471             : #define COLOR_8_TO_16_BIT(_c) ((_c) << 8 | (_c))
     472             : 
     473             : NS_IMETHODIMP
     474           0 : nsGNOMEShellService::GetDesktopBackgroundColor(uint32_t *aColor)
     475             : {
     476             :   nsCOMPtr<nsIGSettingsService> gsettings =
     477           0 :     do_GetService(NS_GSETTINGSSERVICE_CONTRACTID);
     478           0 :   nsCOMPtr<nsIGSettingsCollection> background_settings;
     479           0 :   nsAutoCString background;
     480             : 
     481           0 :   if (gsettings) {
     482           0 :     gsettings->GetCollectionForSchema(
     483           0 :       NS_LITERAL_CSTRING(kDesktopBGSchema), getter_AddRefs(background_settings));
     484           0 :     if (background_settings) {
     485           0 :       background_settings->GetString(NS_LITERAL_CSTRING(kDesktopColorGSKey),
     486           0 :                                      background);
     487             :     }
     488             :   }
     489             : 
     490           0 :   if (!background_settings) {
     491           0 :     nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
     492           0 :     if (gconf)
     493           0 :       gconf->GetString(NS_LITERAL_CSTRING(kDesktopColorKey), background);
     494             :   }
     495             : 
     496           0 :   if (background.IsEmpty()) {
     497           0 :     *aColor = 0;
     498           0 :     return NS_OK;
     499             :   }
     500             : 
     501             :   GdkColor color;
     502           0 :   gboolean success = gdk_color_parse(background.get(), &color);
     503             : 
     504           0 :   NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
     505             : 
     506           0 :   *aColor = COLOR_16_TO_8_BIT(color.red) << 16 |
     507           0 :             COLOR_16_TO_8_BIT(color.green) << 8 |
     508           0 :             COLOR_16_TO_8_BIT(color.blue);
     509           0 :   return NS_OK;
     510             : }
     511             : 
     512             : static void
     513           0 : ColorToCString(uint32_t aColor, nsCString& aResult)
     514             : {
     515             :   // The #rrrrggggbbbb format is used to match gdk_color_to_string()
     516           0 :   aResult.SetLength(13);
     517           0 :   char *buf = aResult.BeginWriting();
     518           0 :   if (!buf)
     519           0 :     return;
     520             : 
     521           0 :   uint16_t red = COLOR_8_TO_16_BIT((aColor >> 16) & 0xff);
     522           0 :   uint16_t green = COLOR_8_TO_16_BIT((aColor >> 8) & 0xff);
     523           0 :   uint16_t blue = COLOR_8_TO_16_BIT(aColor & 0xff);
     524             : 
     525           0 :   snprintf(buf, 14, "#%04x%04x%04x", red, green, blue);
     526             : }
     527             : 
     528             : NS_IMETHODIMP
     529           0 : nsGNOMEShellService::SetDesktopBackgroundColor(uint32_t aColor)
     530             : {
     531           0 :   NS_ASSERTION(aColor <= 0xffffff, "aColor has extra bits");
     532           0 :   nsAutoCString colorString;
     533           0 :   ColorToCString(aColor, colorString);
     534             : 
     535             :   nsCOMPtr<nsIGSettingsService> gsettings =
     536           0 :     do_GetService(NS_GSETTINGSSERVICE_CONTRACTID);
     537           0 :   if (gsettings) {
     538           0 :     nsCOMPtr<nsIGSettingsCollection> background_settings;
     539           0 :     gsettings->GetCollectionForSchema(
     540           0 :       NS_LITERAL_CSTRING(kDesktopBGSchema), getter_AddRefs(background_settings));
     541           0 :     if (background_settings) {
     542           0 :       background_settings->SetString(NS_LITERAL_CSTRING(kDesktopColorGSKey),
     543           0 :                                      colorString);
     544           0 :       return NS_OK;
     545             :     }
     546             :   }
     547             : 
     548           0 :   nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
     549             : 
     550           0 :   if (gconf) {
     551           0 :     gconf->SetString(NS_LITERAL_CSTRING(kDesktopColorKey), colorString);
     552             :   }
     553             : 
     554           0 :   return NS_OK;
     555             : }
     556             : 
     557             : NS_IMETHODIMP
     558           0 : nsGNOMEShellService::OpenApplication(int32_t aApplication)
     559             : {
     560           0 :   nsAutoCString scheme;
     561           0 :   if (aApplication == APPLICATION_MAIL)
     562           0 :     scheme.AssignLiteral("mailto");
     563           0 :   else if (aApplication == APPLICATION_NEWS)
     564           0 :     scheme.AssignLiteral("news");
     565             :   else
     566           0 :     return NS_ERROR_NOT_AVAILABLE;
     567             : 
     568           0 :   nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID);
     569           0 :   if (giovfs) {
     570           0 :     nsCOMPtr<nsIGIOMimeApp> gioApp;
     571           0 :     giovfs->GetAppForURIScheme(scheme, getter_AddRefs(gioApp));
     572           0 :     if (gioApp)
     573           0 :       return gioApp->Launch(EmptyCString());
     574             :   }
     575             : 
     576           0 :   nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
     577           0 :   if (!gconf)
     578           0 :     return NS_ERROR_FAILURE;
     579             : 
     580             :   bool enabled;
     581           0 :   nsAutoCString appCommand;
     582           0 :   gconf->GetAppForProtocol(scheme, &enabled, appCommand);
     583             : 
     584           0 :   if (!enabled)
     585           0 :     return NS_ERROR_FAILURE;
     586             : 
     587             :   // XXX we don't currently handle launching a terminal window.
     588             :   // If the handler requires a terminal, bail.
     589             :   bool requiresTerminal;
     590           0 :   gconf->HandlerRequiresTerminal(scheme, &requiresTerminal);
     591           0 :   if (requiresTerminal)
     592           0 :     return NS_ERROR_FAILURE;
     593             : 
     594             :   // Perform shell argument expansion
     595             :   int argc;
     596             :   char **argv;
     597           0 :   if (!g_shell_parse_argv(appCommand.get(), &argc, &argv, nullptr))
     598           0 :     return NS_ERROR_FAILURE;
     599             : 
     600           0 :   char **newArgv = new char*[argc + 1];
     601           0 :   int newArgc = 0;
     602             : 
     603             :   // Run through the list of arguments.  Copy all of them to the new
     604             :   // argv except for %s, which we skip.
     605           0 :   for (int i = 0; i < argc; ++i) {
     606           0 :     if (strcmp(argv[i], "%s") != 0)
     607           0 :       newArgv[newArgc++] = argv[i];
     608             :   }
     609             : 
     610           0 :   newArgv[newArgc] = nullptr;
     611             : 
     612             :   gboolean err = g_spawn_async(nullptr, newArgv, nullptr, G_SPAWN_SEARCH_PATH,
     613           0 :                                nullptr, nullptr, nullptr, nullptr);
     614             : 
     615           0 :   g_strfreev(argv);
     616           0 :   delete[] newArgv;
     617             : 
     618           0 :   return err ? NS_OK : NS_ERROR_FAILURE;
     619             : }
     620             : 
     621             : NS_IMETHODIMP
     622           0 : nsGNOMEShellService::OpenApplicationWithURI(nsIFile* aApplication, const nsACString& aURI)
     623             : {
     624             :   nsresult rv;
     625             :   nsCOMPtr<nsIProcess> process =
     626           0 :     do_CreateInstance("@mozilla.org/process/util;1", &rv);
     627           0 :   if (NS_FAILED(rv))
     628           0 :     return rv;
     629             : 
     630           0 :   rv = process->Init(aApplication);
     631           0 :   if (NS_FAILED(rv))
     632           0 :     return rv;
     633             : 
     634           0 :   const nsCString spec(aURI);
     635           0 :   const char* specStr = spec.get();
     636           0 :   return process->Run(false, &specStr, 1);
     637             : }
     638             : 
     639             : NS_IMETHODIMP
     640           0 : nsGNOMEShellService::GetDefaultFeedReader(nsIFile** _retval)
     641             : {
     642           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     643             : }

Generated by: LCOV version 1.13