source: pkg/main/iceweasel/trunk/browser/components/shell/src/nsGNOMEShellService.cpp @ 5108

Revision 5108, 18.7 KB checked in by alanbach-guest, 5 years ago (diff)

[svn-inject] Applying Debian modifications to trunk

Line 
1/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 *
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
14 *
15 * The Original Code is Shell Service.
16 *
17 * The Initial Developer of the Original Code is mozilla.org.
18 * Portions created by the Initial Developer are Copyright (C) 2004
19 * the Initial Developer. All Rights Reserved.
20 *
21 * Contributor(s):
22 *
23 * Alternatively, the contents of this file may be used under the terms of
24 * either the GNU General Public License Version 2 or later (the "GPL"), or
25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 * in which case the provisions of the GPL or the LGPL are applicable instead
27 * of those above. If you wish to allow use of your version of this file only
28 * under the terms of either the GPL or the LGPL, and not to allow others to
29 * use your version of this file under the terms of the MPL, indicate your
30 * decision by deleting the provisions above and replace them with the notice
31 * and other provisions required by the GPL or the LGPL. If you do not delete
32 * the provisions above, a recipient may use your version of this file under
33 * the terms of any one of the MPL, the GPL or the LGPL.
34 *
35 * ***** END LICENSE BLOCK ***** */
36
37#include "nsCOMPtr.h"
38#include "nsGNOMEShellService.h"
39#include "nsShellService.h"
40#include "nsIServiceManager.h"
41#include "nsILocalFile.h"
42#include "nsIProperties.h"
43#include "nsDirectoryServiceDefs.h"
44#include "nsIPrefService.h"
45#include "prenv.h"
46#include "nsStringAPI.h"
47#include "nsIGConfService.h"
48#include "nsIGnomeVFSService.h"
49#include "nsIStringBundle.h"
50#include "gfxIImageFrame.h"
51#include "nsIOutputStream.h"
52#include "nsIProcess.h"
53#include "nsNetUtil.h"
54#include "nsIDOMHTMLImageElement.h"
55#include "nsIImageLoadingContent.h"
56#include "imgIRequest.h"
57#include "imgIContainer.h"
58#include "nsIImage.h"
59#include "prprf.h"
60#ifdef MOZ_WIDGET_GTK2
61#include "nsIImageToPixbuf.h"
62#endif
63
64#include <glib.h>
65#include <glib-object.h>
66#include <gdk-pixbuf/gdk-pixbuf.h>
67#include <limits.h>
68#include <stdlib.h>
69
70struct ProtocolAssociation
71{
72  const char *name;
73  PRBool essential;
74};
75
76struct MimeTypeAssociation
77{
78  const char *mimeType;
79  const char *extensions;
80};
81
82static const ProtocolAssociation appProtocols[] = {
83  { "http",   PR_TRUE  },
84  { "https",  PR_TRUE  },
85  { "ftp",    PR_FALSE },
86  { "chrome", PR_FALSE }
87};
88
89static const MimeTypeAssociation appTypes[] = {
90  { "text/html",             "htm html shtml" },
91  { "application/xhtml+xml", "xhtml xht"      }
92};
93
94static const char kDocumentIconPath[] = "firefox-document.png";
95
96// GConf registry key constants
97#define DG_BACKGROUND "/desktop/gnome/background"
98
99static const char kDesktopImageKey[] = DG_BACKGROUND "/picture_filename";
100static const char kDesktopOptionsKey[] = DG_BACKGROUND "/picture_options";
101static const char kDesktopDrawBGKey[] = DG_BACKGROUND "/draw_background";
102static const char kDesktopColorKey[] = DG_BACKGROUND "/primary_color";
103
104nsresult
105nsGNOMEShellService::Init()
106{
107  nsresult rv;
108
109  // GConf and GnomeVFS _must_ be available, or we do not allow
110  // CreateInstance to succeed.
111
112  nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
113  nsCOMPtr<nsIGnomeVFSService> vfs =
114    do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
115
116  if (!gconf || !vfs)
117    return NS_ERROR_NOT_AVAILABLE;
118
119  // Check G_BROKEN_FILENAMES.  If it's set, then filenames in glib use
120  // the locale encoding.  If it's not set, they use UTF-8.
121  mUseLocaleFilenames = PR_GetEnv("G_BROKEN_FILENAMES") != nsnull;
122
123  nsCOMPtr<nsIProperties> dirSvc
124    (do_GetService("@mozilla.org/file/directory_service;1"));
125  NS_ENSURE_TRUE(dirSvc, NS_ERROR_NOT_AVAILABLE);
126
127  nsCOMPtr<nsILocalFile> appPath;
128  rv = dirSvc->Get(NS_XPCOM_CURRENT_PROCESS_DIR, NS_GET_IID(nsILocalFile),
129                   getter_AddRefs(appPath));
130  NS_ENSURE_SUCCESS(rv, rv);
131
132  rv = appPath->AppendNative(NS_LITERAL_CSTRING(MOZ_APP_NAME));
133  NS_ENSURE_SUCCESS(rv, rv);
134
135  return appPath->GetNativePath(mAppPath);
136}
137
138NS_IMPL_ISUPPORTS1(nsGNOMEShellService, nsIShellService)
139
140PRBool
141nsGNOMEShellService::KeyMatchesAppName(const char *aKeyValue) const
142{
143
144  gchar *commandPath;
145  if (mUseLocaleFilenames) {
146    gchar *nativePath = g_filename_from_utf8(aKeyValue, -1, NULL, NULL, NULL);
147    if (!nativePath) {
148      NS_ERROR("Error converting path to filesystem encoding");
149      return PR_FALSE;
150    }
151
152    commandPath = g_find_program_in_path(nativePath);
153    g_free(nativePath);
154  } else {
155    commandPath = g_find_program_in_path(aKeyValue);
156  }
157
158  if (!commandPath)
159    return PR_FALSE;
160
161  PRBool matches = mAppPath.Equals(commandPath);
162  g_free(commandPath);
163  return matches;
164}
165
166NS_IMETHODIMP
167nsGNOMEShellService::IsDefaultBrowser(PRBool aStartupCheck,
168                                      PRBool* aIsDefaultBrowser)
169{
170  *aIsDefaultBrowser = PR_FALSE;
171  if (aStartupCheck)
172    mCheckedThisSession = PR_TRUE;
173
174  nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
175
176  PRBool enabled;
177  nsCAutoString handler;
178
179  for (unsigned int i = 0; i < NS_ARRAY_LENGTH(appProtocols); ++i) {
180    if (!appProtocols[i].essential)
181      continue;
182
183    handler.Truncate();
184    gconf->GetAppForProtocol(nsDependentCString(appProtocols[i].name),
185                             &enabled, handler);
186
187    // The string will be something of the form: [/path/to/]browser "%s"
188    // We want to remove all of the parameters and get just the binary name.
189
190    gint argc;
191    gchar **argv;
192
193    if (g_shell_parse_argv(handler.get(), &argc, &argv, NULL) && argc > 0) {
194      handler.Assign(argv[0]);
195      g_strfreev(argv);
196    }
197
198    if (!KeyMatchesAppName(handler.get()) || !enabled)
199      return NS_OK; // the handler is disabled or set to another app
200  }
201
202  *aIsDefaultBrowser = PR_TRUE;
203
204  return NS_OK;
205}
206
207NS_IMETHODIMP
208nsGNOMEShellService::SetDefaultBrowser(PRBool aClaimAllTypes,
209                                       PRBool aForAllUsers)
210{
211#ifdef DEBUG
212  if (aForAllUsers)
213    NS_WARNING("Setting the default browser for all users is not yet supported");
214#endif
215
216  nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
217
218  nsCAutoString schemeList;
219  nsCAutoString appKeyValue(mAppPath);
220  appKeyValue.Append(" \"%s\"");
221  unsigned int i;
222
223  for (i = 0; i < NS_ARRAY_LENGTH(appProtocols); ++i) {
224    schemeList.Append(nsDependentCString(appProtocols[i].name));
225    schemeList.Append(',');
226
227    if (appProtocols[i].essential || aClaimAllTypes) {
228      gconf->SetAppForProtocol(nsDependentCString(appProtocols[i].name),
229                               appKeyValue);
230    }
231  }
232
233  if (aClaimAllTypes) {
234    nsCOMPtr<nsIGnomeVFSService> vfs =
235      do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID);
236
237    nsCOMPtr<nsIStringBundleService> bundleService =
238      do_GetService(NS_STRINGBUNDLE_CONTRACTID);
239    NS_ENSURE_TRUE(bundleService, NS_ERROR_OUT_OF_MEMORY);
240
241    nsCOMPtr<nsIStringBundle> brandBundle;
242    bundleService->CreateBundle(BRAND_PROPERTIES, getter_AddRefs(brandBundle));
243    NS_ENSURE_TRUE(brandBundle, NS_ERROR_FAILURE);
244
245    nsString brandShortName, brandFullName;
246    brandBundle->GetStringFromName(NS_LITERAL_STRING("brandShortName").get(),
247                                   getter_Copies(brandShortName));
248    brandBundle->GetStringFromName(NS_LITERAL_STRING("brandFullName").get(),
249                                   getter_Copies(brandFullName));
250
251    // use brandShortName as the application id.
252    NS_ConvertUTF16toUTF8 id(brandShortName);
253
254    vfs->SetAppStringKey(id, nsIGnomeVFSService::APP_KEY_COMMAND, mAppPath);
255    vfs->SetAppStringKey(id, nsIGnomeVFSService::APP_KEY_NAME,
256                         NS_ConvertUTF16toUTF8(brandFullName));
257
258    // We don't want to be the default handler for "file:", but we do
259    // want Nautilus to know that we support file: if the MIME type is
260    // one that we can handle.
261
262    schemeList.Append("file");
263
264    vfs->SetAppStringKey(id, nsIGnomeVFSService::APP_KEY_SUPPORTED_URI_SCHEMES,
265                         schemeList);
266
267    vfs->SetAppStringKey(id, nsIGnomeVFSService::APP_KEY_EXPECTS_URIS,
268                         NS_LITERAL_CSTRING("true"));
269
270    vfs->SetAppBoolKey(id, nsIGnomeVFSService::APP_KEY_CAN_OPEN_MULTIPLE,
271                       PR_FALSE);
272
273    vfs->SetAppBoolKey(id, nsIGnomeVFSService::APP_KEY_REQUIRES_TERMINAL,
274                       PR_FALSE);
275
276    // Copy icons/document.png to ~/.icons/firefox-document.png
277    nsCAutoString iconFilePath(mAppPath);
278    PRInt32 lastSlash = iconFilePath.RFindChar(PRUnichar('/'));
279    if (lastSlash == -1) {
280      NS_ERROR("no slash in executable path?");
281    } else {
282      iconFilePath.SetLength(lastSlash);
283      nsCOMPtr<nsILocalFile> iconFile;
284      NS_NewNativeLocalFile(iconFilePath, PR_FALSE, getter_AddRefs(iconFile));
285      if (iconFile) {
286        iconFile->AppendRelativeNativePath(NS_LITERAL_CSTRING("icons/document.png"));
287
288        nsCOMPtr<nsILocalFile> userIconPath;
289        NS_NewNativeLocalFile(nsDependentCString(PR_GetEnv("HOME")), PR_FALSE,
290                              getter_AddRefs(userIconPath));
291        if (userIconPath) {
292          userIconPath->AppendNative(NS_LITERAL_CSTRING(".icons"));
293          iconFile->CopyToNative(userIconPath,
294                                 nsDependentCString(kDocumentIconPath));
295        }
296      }
297    }
298
299    for (i = 0; i < NS_ARRAY_LENGTH(appTypes); ++i) {
300      vfs->AddMimeType(id, nsDependentCString(appTypes[i].mimeType));
301      vfs->SetMimeExtensions(nsDependentCString(appTypes[i].mimeType),
302                             nsDependentCString(appTypes[i].extensions));
303      vfs->SetAppForMimeType(nsDependentCString(appTypes[i].mimeType), id);
304      vfs->SetIconForMimeType(nsDependentCString(appTypes[i].mimeType),
305                              NS_LITERAL_CSTRING(kDocumentIconPath));
306    }
307
308    vfs->SyncAppRegistry();
309  }
310
311  return NS_OK;
312}
313
314NS_IMETHODIMP
315nsGNOMEShellService::GetShouldCheckDefaultBrowser(PRBool* aResult)
316{
317  // If we've already checked, the browser has been started and this is a
318  // new window open, and we don't want to check again.
319  if (mCheckedThisSession) {
320    *aResult = PR_FALSE;
321    return NS_OK;
322  }
323
324  nsCOMPtr<nsIPrefBranch> prefs;
325  nsCOMPtr<nsIPrefService> pserve(do_GetService(NS_PREFSERVICE_CONTRACTID));
326  if (pserve)
327    pserve->GetBranch("", getter_AddRefs(prefs));
328
329  prefs->GetBoolPref(PREF_CHECKDEFAULTBROWSER, aResult);
330
331  return NS_OK;
332}
333
334NS_IMETHODIMP
335nsGNOMEShellService::SetShouldCheckDefaultBrowser(PRBool aShouldCheck)
336{
337  nsCOMPtr<nsIPrefBranch> prefs;
338  nsCOMPtr<nsIPrefService> pserve(do_GetService(NS_PREFSERVICE_CONTRACTID));
339  if (pserve)
340    pserve->GetBranch("", getter_AddRefs(prefs));
341
342  prefs->SetBoolPref(PREF_CHECKDEFAULTBROWSER, aShouldCheck);
343
344  return NS_OK;
345}
346
347static nsresult
348WriteImage(const nsCString& aPath, gfxIImageFrame* aImage)
349{
350  nsCOMPtr<nsIImage> img(do_GetInterface(aImage));
351  if (!img)
352      return NS_ERROR_NOT_AVAILABLE;
353
354#ifndef MOZ_WIDGET_GTK2
355  return NS_ERROR_NOT_AVAILABLE;
356#else
357  nsCOMPtr<nsIImageToPixbuf> imgToPixbuf =
358    do_GetService("@mozilla.org/widget/image-to-gdk-pixbuf;1");
359  if (!imgToPixbuf)
360      return NS_ERROR_NOT_AVAILABLE;
361
362  GdkPixbuf* pixbuf = imgToPixbuf->ConvertImageToPixbuf(img);
363  if (!pixbuf)
364      return NS_ERROR_NOT_AVAILABLE;
365
366  gboolean res = gdk_pixbuf_save(pixbuf, aPath.get(), "png", NULL, NULL);
367
368  g_object_unref(pixbuf);
369  return res ? NS_OK : NS_ERROR_FAILURE;
370#endif
371}
372                 
373NS_IMETHODIMP
374nsGNOMEShellService::SetDesktopBackground(nsIDOMElement* aElement, 
375                                          PRInt32 aPosition)
376{
377  nsresult rv;
378  nsCOMPtr<gfxIImageFrame> gfxFrame;
379
380  nsCOMPtr<nsIImageLoadingContent> imageContent = do_QueryInterface(aElement, &rv);
381  if (!imageContent) return rv;
382
383  // get the image container
384  nsCOMPtr<imgIRequest> request;
385  rv = imageContent->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
386                                getter_AddRefs(request));
387  if (!request) return rv;
388  nsCOMPtr<imgIContainer> container;
389  rv = request->GetImage(getter_AddRefs(container));
390  if (!container) return rv;
391
392  // get the current frame, which holds the image data
393  container->GetCurrentFrame(getter_AddRefs(gfxFrame));
394
395  if (!gfxFrame)
396    return NS_ERROR_FAILURE;
397
398  // Write the background file to the home directory.
399  nsCAutoString filePath(PR_GetEnv("HOME"));
400
401  // get the product brand name from localized strings
402  nsString brandName;
403  nsCID bundleCID = NS_STRINGBUNDLESERVICE_CID;
404  nsCOMPtr<nsIStringBundleService> bundleService(do_GetService(bundleCID));
405  if (bundleService) {
406    nsCOMPtr<nsIStringBundle> brandBundle;
407    rv = bundleService->CreateBundle(BRAND_PROPERTIES,
408                                     getter_AddRefs(brandBundle));
409    if (NS_SUCCEEDED(rv) && brandBundle) {
410      rv = brandBundle->GetStringFromName(NS_LITERAL_STRING("brandShortName").get(),
411                                          getter_Copies(brandName));
412      NS_ENSURE_SUCCESS(rv, rv);
413    }
414  }
415
416  // build the file name
417  filePath.Append('/');
418  filePath.Append(NS_ConvertUTF16toUTF8(brandName));
419  filePath.Append("_wallpaper.png");
420
421  // write the image to a file in the home dir
422  rv = WriteImage(filePath, gfxFrame);
423
424  // if the file was written successfully, set it as the system wallpaper
425  nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
426
427  nsCAutoString options;
428  if (aPosition == BACKGROUND_TILE)
429    options.Assign("wallpaper");
430  else if (aPosition == BACKGROUND_STRETCH)
431    options.Assign("stretched");
432  else
433    options.Assign("centered");
434
435  gconf->SetString(NS_LITERAL_CSTRING(kDesktopOptionsKey), options);
436
437  // Set the image to an empty string first to force a refresh
438  // (since we could be writing a new image on top of an existing
439  // Firefox_wallpaper.png and nautilus doesn't monitor the file for changes)
440  gconf->SetString(NS_LITERAL_CSTRING(kDesktopImageKey),
441                   EmptyCString());
442
443  gconf->SetString(NS_LITERAL_CSTRING(kDesktopImageKey), filePath);
444  gconf->SetBool(NS_LITERAL_CSTRING(kDesktopDrawBGKey), PR_TRUE);
445
446  return rv;
447}
448
449// In: pointer to two characters CC
450// Out: parsed color number
451static PRUint8
452HexToNum(char ch)
453{
454  if ('0' <= ch && '9' >= ch)
455    return ch - '0';
456
457  if ('A' <= ch && 'F' >= ch)
458    return ch - 'A' + 10;
459
460  if ('a' <= ch && 'f' >= ch)
461    return ch - 'a' + 10;
462
463  return 0;
464}
465 
466
467// In: 3, 6 or 12-character RRGGBB hex string
468// Out: component colors
469static PRBool
470HexToRGB(const nsCString& aColorSpec,
471         PRUint8 &aRed,
472         PRUint8 &aGreen,
473         PRUint8 &aBlue)
474{
475  const char *buf = aColorSpec.get();
476
477  if (aColorSpec.Length() == 12) {
478    aRed =    HexToNum(buf[0]) << 4 |
479              HexToNum(buf[1]);
480    aGreen =  HexToNum(buf[4]) << 4 |
481              HexToNum(buf[5]);
482    aBlue =   HexToNum(buf[8]) << 4 |
483              HexToNum(buf[9]);
484    return PR_TRUE;
485  }
486
487  if (aColorSpec.Length() == 6) {
488    aRed =    HexToNum(buf[0]) << 4 |
489              HexToNum(buf[1]);
490    aGreen =  HexToNum(buf[2]) << 4 |
491              HexToNum(buf[3]);
492    aBlue =   HexToNum(buf[4]) << 4 |
493              HexToNum(buf[5]);
494    return PR_TRUE;
495  }
496
497  if (aColorSpec.Length() == 3) {
498    aRed = HexToNum(buf[0]);
499    aGreen = HexToNum(buf[1]);
500    aBlue = HexToNum(buf[2]);
501
502    aRed |= aRed << 4;
503    aGreen |= aGreen << 4;
504    aBlue |= aBlue << 4;
505
506    return PR_TRUE;
507  }
508
509  return PR_FALSE;
510}
511
512NS_IMETHODIMP
513nsGNOMEShellService::GetDesktopBackgroundColor(PRUint32 *aColor)
514{
515  nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
516
517  nsCAutoString background;
518  gconf->GetString(NS_LITERAL_CSTRING(kDesktopColorKey), background);
519
520  if (background.IsEmpty()) {
521    *aColor = 0;
522    return NS_OK;
523  }
524
525  // Chop off the leading '#' character
526  background.Cut(0, 1);
527
528  PRUint8 red, green, blue;
529  if (!HexToRGB(background, red, green, blue))
530      return NS_ERROR_FAILURE;
531
532  // The result must be in RGB order with the high 8 bits zero.
533  *aColor = (red << 16 | green << 8  | blue);
534  return NS_OK;
535}
536
537static void
538ColorToHex(PRUint32 aColor, nsCString& aResult)
539{
540  char *buf = aResult.BeginWriting(7);
541  if (!buf)
542    return;
543
544  PRUint8 red = (aColor >> 16);
545  PRUint8 green = (aColor >> 8) & 0xff;
546  PRUint8 blue = aColor & 0xff;
547
548  PR_snprintf(buf, 8, "#%02x%02x%02x", red, green, blue);
549}
550
551NS_IMETHODIMP
552nsGNOMEShellService::SetDesktopBackgroundColor(PRUint32 aColor)
553{
554  nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
555
556  nsCString colorString;
557  ColorToHex(aColor, colorString);
558
559  gconf->SetString(NS_LITERAL_CSTRING(kDesktopColorKey), colorString);
560
561  return NS_OK;
562}
563
564NS_IMETHODIMP
565nsGNOMEShellService::OpenApplication(PRInt32 aApplication)
566{
567  nsCAutoString scheme;
568  if (aApplication == APPLICATION_MAIL)
569    scheme.Assign("mailto");
570  else if (aApplication == APPLICATION_NEWS)
571    scheme.Assign("news");
572  else
573    return NS_ERROR_NOT_AVAILABLE;
574
575  nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
576
577  PRBool enabled;
578  nsCAutoString appCommand;
579  gconf->GetAppForProtocol(scheme, &enabled, appCommand);
580
581  if (!enabled)
582    return NS_ERROR_FAILURE;
583
584  // XXX we don't currently handle launching a terminal window.
585  // If the handler requires a terminal, bail.
586  PRBool requiresTerminal;
587  gconf->HandlerRequiresTerminal(scheme, &requiresTerminal);
588  if (requiresTerminal)
589    return NS_ERROR_FAILURE;
590
591  // Perform shell argument expansion
592  int argc;
593  char **argv;
594  if (!g_shell_parse_argv(appCommand.get(), &argc, &argv, NULL))
595    return NS_ERROR_FAILURE;
596
597  char **newArgv = new char*[argc + 1];
598  int newArgc = 0;
599
600  // Run through the list of arguments.  Copy all of them to the new
601  // argv except for %s, which we skip.
602  for (int i = 0; i < argc; ++i) {
603    if (strcmp(argv[i], "%s") != 0)
604      newArgv[newArgc++] = argv[i];
605  }
606
607  newArgv[newArgc] = nsnull;
608
609  gboolean err = g_spawn_async(NULL, newArgv, NULL, G_SPAWN_SEARCH_PATH,
610                               NULL, NULL, NULL, NULL);
611
612  g_strfreev(argv);
613  delete[] newArgv;
614
615  return err ? NS_OK : NS_ERROR_FAILURE;
616}
617
618NS_IMETHODIMP
619nsGNOMEShellService::OpenApplicationWithURI(nsILocalFile* aApplication, const nsACString& aURI)
620{
621  nsresult rv;
622  nsCOMPtr<nsIProcess> process = 
623    do_CreateInstance("@mozilla.org/process/util;1", &rv);
624  if (NS_FAILED(rv))
625    return rv;
626 
627  rv = process->Init(aApplication);
628  if (NS_FAILED(rv))
629    return rv;
630
631  const nsCString spec(aURI);
632  const char* specStr = spec.get();
633  PRUint32 pid;
634  return process->Run(PR_FALSE, &specStr, 1, &pid);
635}
636
637NS_IMETHODIMP
638nsGNOMEShellService::GetDefaultFeedReader(nsILocalFile** _retval)
639{
640  return NS_ERROR_NOT_IMPLEMENTED;
641}
Note: See TracBrowser for help on using the repository browser.