toolkit/system/gnome/nsGConfService.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toolkit/system/gnome/nsGConfService.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,305 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#include "mozilla/ArrayUtils.h"
    1.10 +#include "nsGConfService.h"
    1.11 +#include "nsStringAPI.h"
    1.12 +#include "nsCOMPtr.h"
    1.13 +#include "nsComponentManagerUtils.h"
    1.14 +#include "nsISupportsPrimitives.h"
    1.15 +#include "nsIMutableArray.h"
    1.16 +#include "prlink.h"
    1.17 +
    1.18 +#include <gconf/gconf-client.h>
    1.19 +
    1.20 +using namespace mozilla;
    1.21 +
    1.22 +#define GCONF_FUNCTIONS \
    1.23 +  FUNC(gconf_client_get_default, GConfClient*, (void)) \
    1.24 +  FUNC(gconf_client_get_bool, gboolean, (GConfClient*, const gchar*, GError**)) \
    1.25 +  FUNC(gconf_client_get_string, gchar*, (GConfClient*, const gchar*, GError**)) \
    1.26 +  FUNC(gconf_client_get_int, gint, (GConfClient*, const gchar*, GError**)) \
    1.27 +  FUNC(gconf_client_get_float, gdouble, (GConfClient*, const gchar*, GError**)) \
    1.28 +  FUNC(gconf_client_get_list, GSList*, (GConfClient*, const gchar*, GConfValueType, GError**)) \
    1.29 +  FUNC(gconf_client_set_bool, gboolean, (GConfClient*, const gchar*, gboolean, GError**)) \
    1.30 +  FUNC(gconf_client_set_string, gboolean, (GConfClient*, const gchar*, const gchar*, GError**)) \
    1.31 +  FUNC(gconf_client_set_int, gboolean, (GConfClient*, const gchar*, gint, GError**)) \
    1.32 +  FUNC(gconf_client_set_float, gboolean, (GConfClient*, const gchar*, gdouble, GError**)) \
    1.33 +  FUNC(gconf_client_unset, gboolean, (GConfClient*, const gchar*, GError**))
    1.34 +
    1.35 +#define FUNC(name, type, params) \
    1.36 +  typedef type (*_##name##_fn) params; \
    1.37 +  static _##name##_fn _##name;
    1.38 +
    1.39 +GCONF_FUNCTIONS
    1.40 +
    1.41 +#undef FUNC
    1.42 +
    1.43 +#define gconf_client_get_default _gconf_client_get_default
    1.44 +#define gconf_client_get_bool _gconf_client_get_bool
    1.45 +#define gconf_client_get_string _gconf_client_get_string
    1.46 +#define gconf_client_get_int _gconf_client_get_int
    1.47 +#define gconf_client_get_float _gconf_client_get_float
    1.48 +#define gconf_client_get_list _gconf_client_get_list
    1.49 +#define gconf_client_set_bool _gconf_client_set_bool
    1.50 +#define gconf_client_set_string _gconf_client_set_string
    1.51 +#define gconf_client_set_int _gconf_client_set_int
    1.52 +#define gconf_client_set_float _gconf_client_set_float
    1.53 +#define gconf_client_unset _gconf_client_unset
    1.54 +
    1.55 +static PRLibrary *gconfLib = nullptr;
    1.56 +
    1.57 +typedef void (*nsGConfFunc)();
    1.58 +struct nsGConfDynamicFunction {
    1.59 +  const char *functionName;
    1.60 +  nsGConfFunc *function;
    1.61 +};
    1.62 +
    1.63 +nsGConfService::~nsGConfService()
    1.64 +{
    1.65 +  if (mClient)
    1.66 +    g_object_unref(mClient);
    1.67 +
    1.68 +  // We don't unload gconf here because liborbit uses atexit(). In addition to
    1.69 +  // this, it's not a good idea to unload any gobject based library, as it
    1.70 +  // leaves types registered in glib's type system
    1.71 +}
    1.72 +
    1.73 +nsresult
    1.74 +nsGConfService::Init()
    1.75 +{
    1.76 +#define FUNC(name, type, params) { #name, (nsGConfFunc *)&_##name },
    1.77 +  static const nsGConfDynamicFunction kGConfSymbols[] = {
    1.78 +    GCONF_FUNCTIONS
    1.79 +  };
    1.80 +#undef FUNC
    1.81 +
    1.82 +  if (!gconfLib) {
    1.83 +    gconfLib = PR_LoadLibrary("libgconf-2.so.4");
    1.84 +    if (!gconfLib)
    1.85 +      return NS_ERROR_FAILURE;
    1.86 +  }
    1.87 +
    1.88 +  for (uint32_t i = 0; i < ArrayLength(kGConfSymbols); i++) {
    1.89 +    *kGConfSymbols[i].function =
    1.90 +      PR_FindFunctionSymbol(gconfLib, kGConfSymbols[i].functionName);
    1.91 +    if (!*kGConfSymbols[i].function) {
    1.92 +      return NS_ERROR_FAILURE;
    1.93 +    }
    1.94 +  }
    1.95 +
    1.96 +  mClient = gconf_client_get_default();
    1.97 +  return mClient ? NS_OK : NS_ERROR_FAILURE;
    1.98 +}
    1.99 +
   1.100 +NS_IMPL_ISUPPORTS(nsGConfService, nsIGConfService)
   1.101 +
   1.102 +NS_IMETHODIMP
   1.103 +nsGConfService::GetBool(const nsACString &aKey, bool *aResult)
   1.104 +{
   1.105 +  GError* error = nullptr;
   1.106 +  *aResult = gconf_client_get_bool(mClient, PromiseFlatCString(aKey).get(),
   1.107 +                                   &error);
   1.108 +
   1.109 +  if (error) {
   1.110 +    g_error_free(error);
   1.111 +    return NS_ERROR_FAILURE;
   1.112 +  }
   1.113 +
   1.114 +  return NS_OK;
   1.115 +}
   1.116 +
   1.117 +NS_IMETHODIMP
   1.118 +nsGConfService::GetString(const nsACString &aKey, nsACString &aResult)
   1.119 +{
   1.120 +  GError* error = nullptr;
   1.121 +  gchar *result = gconf_client_get_string(mClient,
   1.122 +                                          PromiseFlatCString(aKey).get(),
   1.123 +                                          &error);
   1.124 +
   1.125 +  if (error) {
   1.126 +    g_error_free(error);
   1.127 +    return NS_ERROR_FAILURE;
   1.128 +  }
   1.129 +
   1.130 +  // We do a string copy here so that the caller doesn't need to worry about
   1.131 +  // freeing the string with g_free().
   1.132 +
   1.133 +  aResult.Assign(result);
   1.134 +  g_free(result);
   1.135 +
   1.136 +  return NS_OK;
   1.137 +}
   1.138 +
   1.139 +NS_IMETHODIMP
   1.140 +nsGConfService::GetInt(const nsACString &aKey, int32_t* aResult)
   1.141 +{
   1.142 +  GError* error = nullptr;
   1.143 +  *aResult = gconf_client_get_int(mClient, PromiseFlatCString(aKey).get(),
   1.144 +                                  &error);
   1.145 +
   1.146 +  if (error) {
   1.147 +    g_error_free(error);
   1.148 +    return NS_ERROR_FAILURE;
   1.149 +  }
   1.150 +
   1.151 +  return NS_OK;
   1.152 +}
   1.153 +
   1.154 +NS_IMETHODIMP
   1.155 +nsGConfService::GetFloat(const nsACString &aKey, float* aResult)
   1.156 +{
   1.157 +  GError* error = nullptr;
   1.158 +  *aResult = gconf_client_get_float(mClient, PromiseFlatCString(aKey).get(),
   1.159 +                                    &error);
   1.160 +
   1.161 +  if (error) {
   1.162 +    g_error_free(error);
   1.163 +    return NS_ERROR_FAILURE;
   1.164 +  }
   1.165 +
   1.166 +  return NS_OK;
   1.167 +}
   1.168 +
   1.169 +NS_IMETHODIMP
   1.170 +nsGConfService::GetStringList(const nsACString &aKey, nsIArray** aResult)
   1.171 +{
   1.172 +  nsCOMPtr<nsIMutableArray> items(do_CreateInstance(NS_ARRAY_CONTRACTID));
   1.173 +  if (!items)
   1.174 +    return NS_ERROR_OUT_OF_MEMORY;
   1.175 +    
   1.176 +  GError* error = nullptr;
   1.177 +  GSList* list = gconf_client_get_list(mClient, PromiseFlatCString(aKey).get(),
   1.178 +                                       GCONF_VALUE_STRING, &error);
   1.179 +  if (error) {
   1.180 +    g_error_free(error);
   1.181 +    return NS_ERROR_FAILURE;
   1.182 +  }
   1.183 +
   1.184 +  for (GSList* l = list; l; l = l->next) {
   1.185 +    nsCOMPtr<nsISupportsString> obj(do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
   1.186 +    if (!obj) {
   1.187 +      g_slist_free(list);
   1.188 +      return NS_ERROR_OUT_OF_MEMORY;
   1.189 +    }
   1.190 +    obj->SetData(NS_ConvertUTF8toUTF16((const char*)l->data));
   1.191 +    items->AppendElement(obj, false);
   1.192 +    g_free(l->data);
   1.193 +  }
   1.194 +  
   1.195 +  g_slist_free(list);
   1.196 +  NS_ADDREF(*aResult = items);
   1.197 +  return NS_OK;
   1.198 +}
   1.199 +
   1.200 +NS_IMETHODIMP
   1.201 +nsGConfService::SetBool(const nsACString &aKey, bool aValue)
   1.202 +{
   1.203 +  bool res = gconf_client_set_bool(mClient, PromiseFlatCString(aKey).get(),
   1.204 +                                     aValue, nullptr);
   1.205 +
   1.206 +  return res ? NS_OK : NS_ERROR_FAILURE;
   1.207 +}
   1.208 +
   1.209 +NS_IMETHODIMP
   1.210 +nsGConfService::SetString(const nsACString &aKey, const nsACString &aValue)
   1.211 +{
   1.212 +  bool res = gconf_client_set_string(mClient, PromiseFlatCString(aKey).get(),
   1.213 +                                       PromiseFlatCString(aValue).get(),
   1.214 +                                       nullptr);
   1.215 +
   1.216 +  return res ? NS_OK : NS_ERROR_FAILURE;
   1.217 +}
   1.218 +
   1.219 +NS_IMETHODIMP
   1.220 +nsGConfService::SetInt(const nsACString &aKey, int32_t aValue)
   1.221 +{
   1.222 +  bool res = gconf_client_set_int(mClient, PromiseFlatCString(aKey).get(),
   1.223 +                                    aValue, nullptr);
   1.224 +
   1.225 +  return res ? NS_OK : NS_ERROR_FAILURE;
   1.226 +}
   1.227 +
   1.228 +NS_IMETHODIMP
   1.229 +nsGConfService::SetFloat(const nsACString &aKey, float aValue)
   1.230 +{
   1.231 +  bool res = gconf_client_set_float(mClient, PromiseFlatCString(aKey).get(),
   1.232 +                                      aValue, nullptr);
   1.233 +
   1.234 +  return res ? NS_OK : NS_ERROR_FAILURE;
   1.235 +}
   1.236 +
   1.237 +NS_IMETHODIMP
   1.238 +nsGConfService::GetAppForProtocol(const nsACString &aScheme, bool *aEnabled,
   1.239 +                                  nsACString &aHandler)
   1.240 +{
   1.241 +  nsAutoCString key("/desktop/gnome/url-handlers/");
   1.242 +  key.Append(aScheme);
   1.243 +  key.Append("/command");
   1.244 +
   1.245 +  GError *err = nullptr;
   1.246 +  gchar *command = gconf_client_get_string(mClient, key.get(), &err);
   1.247 +  if (!err && command) {
   1.248 +    key.Replace(key.Length() - 7, 7, NS_LITERAL_CSTRING("enabled"));
   1.249 +    *aEnabled = gconf_client_get_bool(mClient, key.get(), &err);
   1.250 +  } else {
   1.251 +    *aEnabled = false;
   1.252 +  }
   1.253 +
   1.254 +  aHandler.Assign(command);
   1.255 +  g_free(command);
   1.256 +
   1.257 +  if (err) {
   1.258 +    g_error_free(err);
   1.259 +    return NS_ERROR_FAILURE;
   1.260 +  }
   1.261 +
   1.262 +  return NS_OK;
   1.263 +}
   1.264 +
   1.265 +NS_IMETHODIMP
   1.266 +nsGConfService::HandlerRequiresTerminal(const nsACString &aScheme,
   1.267 +                                        bool *aResult)
   1.268 +{
   1.269 +  nsAutoCString key("/desktop/gnome/url-handlers/");
   1.270 +  key.Append(aScheme);
   1.271 +  key.Append("/requires_terminal");
   1.272 +
   1.273 +  GError *err = nullptr;
   1.274 +  *aResult = gconf_client_get_bool(mClient, key.get(), &err);
   1.275 +  if (err) {
   1.276 +    g_error_free(err);
   1.277 +    return NS_ERROR_FAILURE;
   1.278 +  }
   1.279 +
   1.280 +  return NS_OK;
   1.281 +}
   1.282 +
   1.283 +NS_IMETHODIMP
   1.284 +nsGConfService::SetAppForProtocol(const nsACString &aScheme,
   1.285 +                                  const nsACString &aCommand)
   1.286 +{
   1.287 +  nsAutoCString key("/desktop/gnome/url-handlers/");
   1.288 +  key.Append(aScheme);
   1.289 +  key.Append("/command");
   1.290 +
   1.291 +  bool res = gconf_client_set_string(mClient, key.get(),
   1.292 +                                       PromiseFlatCString(aCommand).get(),
   1.293 +                                       nullptr);
   1.294 +  if (res) {
   1.295 +    key.Replace(key.Length() - 7, 7, NS_LITERAL_CSTRING("enabled"));
   1.296 +    res = gconf_client_set_bool(mClient, key.get(), true, nullptr);
   1.297 +    if (res) {
   1.298 +      key.Replace(key.Length() - 7, 7, NS_LITERAL_CSTRING("needs_terminal"));
   1.299 +      res = gconf_client_set_bool(mClient, key.get(), false, nullptr);
   1.300 +      if (res) {
   1.301 +        key.Replace(key.Length() - 14, 14, NS_LITERAL_CSTRING("command-id"));
   1.302 +        res = gconf_client_unset(mClient, key.get(), nullptr);
   1.303 +      }
   1.304 +    }
   1.305 +  }
   1.306 +
   1.307 +  return res ? NS_OK : NS_ERROR_FAILURE;
   1.308 +}

mercurial