Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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/. */
6 #include "mozilla/ArrayUtils.h"
7 #include "nsGConfService.h"
8 #include "nsStringAPI.h"
9 #include "nsCOMPtr.h"
10 #include "nsComponentManagerUtils.h"
11 #include "nsISupportsPrimitives.h"
12 #include "nsIMutableArray.h"
13 #include "prlink.h"
15 #include <gconf/gconf-client.h>
17 using namespace mozilla;
19 #define GCONF_FUNCTIONS \
20 FUNC(gconf_client_get_default, GConfClient*, (void)) \
21 FUNC(gconf_client_get_bool, gboolean, (GConfClient*, const gchar*, GError**)) \
22 FUNC(gconf_client_get_string, gchar*, (GConfClient*, const gchar*, GError**)) \
23 FUNC(gconf_client_get_int, gint, (GConfClient*, const gchar*, GError**)) \
24 FUNC(gconf_client_get_float, gdouble, (GConfClient*, const gchar*, GError**)) \
25 FUNC(gconf_client_get_list, GSList*, (GConfClient*, const gchar*, GConfValueType, GError**)) \
26 FUNC(gconf_client_set_bool, gboolean, (GConfClient*, const gchar*, gboolean, GError**)) \
27 FUNC(gconf_client_set_string, gboolean, (GConfClient*, const gchar*, const gchar*, GError**)) \
28 FUNC(gconf_client_set_int, gboolean, (GConfClient*, const gchar*, gint, GError**)) \
29 FUNC(gconf_client_set_float, gboolean, (GConfClient*, const gchar*, gdouble, GError**)) \
30 FUNC(gconf_client_unset, gboolean, (GConfClient*, const gchar*, GError**))
32 #define FUNC(name, type, params) \
33 typedef type (*_##name##_fn) params; \
34 static _##name##_fn _##name;
36 GCONF_FUNCTIONS
38 #undef FUNC
40 #define gconf_client_get_default _gconf_client_get_default
41 #define gconf_client_get_bool _gconf_client_get_bool
42 #define gconf_client_get_string _gconf_client_get_string
43 #define gconf_client_get_int _gconf_client_get_int
44 #define gconf_client_get_float _gconf_client_get_float
45 #define gconf_client_get_list _gconf_client_get_list
46 #define gconf_client_set_bool _gconf_client_set_bool
47 #define gconf_client_set_string _gconf_client_set_string
48 #define gconf_client_set_int _gconf_client_set_int
49 #define gconf_client_set_float _gconf_client_set_float
50 #define gconf_client_unset _gconf_client_unset
52 static PRLibrary *gconfLib = nullptr;
54 typedef void (*nsGConfFunc)();
55 struct nsGConfDynamicFunction {
56 const char *functionName;
57 nsGConfFunc *function;
58 };
60 nsGConfService::~nsGConfService()
61 {
62 if (mClient)
63 g_object_unref(mClient);
65 // We don't unload gconf here because liborbit uses atexit(). In addition to
66 // this, it's not a good idea to unload any gobject based library, as it
67 // leaves types registered in glib's type system
68 }
70 nsresult
71 nsGConfService::Init()
72 {
73 #define FUNC(name, type, params) { #name, (nsGConfFunc *)&_##name },
74 static const nsGConfDynamicFunction kGConfSymbols[] = {
75 GCONF_FUNCTIONS
76 };
77 #undef FUNC
79 if (!gconfLib) {
80 gconfLib = PR_LoadLibrary("libgconf-2.so.4");
81 if (!gconfLib)
82 return NS_ERROR_FAILURE;
83 }
85 for (uint32_t i = 0; i < ArrayLength(kGConfSymbols); i++) {
86 *kGConfSymbols[i].function =
87 PR_FindFunctionSymbol(gconfLib, kGConfSymbols[i].functionName);
88 if (!*kGConfSymbols[i].function) {
89 return NS_ERROR_FAILURE;
90 }
91 }
93 mClient = gconf_client_get_default();
94 return mClient ? NS_OK : NS_ERROR_FAILURE;
95 }
97 NS_IMPL_ISUPPORTS(nsGConfService, nsIGConfService)
99 NS_IMETHODIMP
100 nsGConfService::GetBool(const nsACString &aKey, bool *aResult)
101 {
102 GError* error = nullptr;
103 *aResult = gconf_client_get_bool(mClient, PromiseFlatCString(aKey).get(),
104 &error);
106 if (error) {
107 g_error_free(error);
108 return NS_ERROR_FAILURE;
109 }
111 return NS_OK;
112 }
114 NS_IMETHODIMP
115 nsGConfService::GetString(const nsACString &aKey, nsACString &aResult)
116 {
117 GError* error = nullptr;
118 gchar *result = gconf_client_get_string(mClient,
119 PromiseFlatCString(aKey).get(),
120 &error);
122 if (error) {
123 g_error_free(error);
124 return NS_ERROR_FAILURE;
125 }
127 // We do a string copy here so that the caller doesn't need to worry about
128 // freeing the string with g_free().
130 aResult.Assign(result);
131 g_free(result);
133 return NS_OK;
134 }
136 NS_IMETHODIMP
137 nsGConfService::GetInt(const nsACString &aKey, int32_t* aResult)
138 {
139 GError* error = nullptr;
140 *aResult = gconf_client_get_int(mClient, PromiseFlatCString(aKey).get(),
141 &error);
143 if (error) {
144 g_error_free(error);
145 return NS_ERROR_FAILURE;
146 }
148 return NS_OK;
149 }
151 NS_IMETHODIMP
152 nsGConfService::GetFloat(const nsACString &aKey, float* aResult)
153 {
154 GError* error = nullptr;
155 *aResult = gconf_client_get_float(mClient, PromiseFlatCString(aKey).get(),
156 &error);
158 if (error) {
159 g_error_free(error);
160 return NS_ERROR_FAILURE;
161 }
163 return NS_OK;
164 }
166 NS_IMETHODIMP
167 nsGConfService::GetStringList(const nsACString &aKey, nsIArray** aResult)
168 {
169 nsCOMPtr<nsIMutableArray> items(do_CreateInstance(NS_ARRAY_CONTRACTID));
170 if (!items)
171 return NS_ERROR_OUT_OF_MEMORY;
173 GError* error = nullptr;
174 GSList* list = gconf_client_get_list(mClient, PromiseFlatCString(aKey).get(),
175 GCONF_VALUE_STRING, &error);
176 if (error) {
177 g_error_free(error);
178 return NS_ERROR_FAILURE;
179 }
181 for (GSList* l = list; l; l = l->next) {
182 nsCOMPtr<nsISupportsString> obj(do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
183 if (!obj) {
184 g_slist_free(list);
185 return NS_ERROR_OUT_OF_MEMORY;
186 }
187 obj->SetData(NS_ConvertUTF8toUTF16((const char*)l->data));
188 items->AppendElement(obj, false);
189 g_free(l->data);
190 }
192 g_slist_free(list);
193 NS_ADDREF(*aResult = items);
194 return NS_OK;
195 }
197 NS_IMETHODIMP
198 nsGConfService::SetBool(const nsACString &aKey, bool aValue)
199 {
200 bool res = gconf_client_set_bool(mClient, PromiseFlatCString(aKey).get(),
201 aValue, nullptr);
203 return res ? NS_OK : NS_ERROR_FAILURE;
204 }
206 NS_IMETHODIMP
207 nsGConfService::SetString(const nsACString &aKey, const nsACString &aValue)
208 {
209 bool res = gconf_client_set_string(mClient, PromiseFlatCString(aKey).get(),
210 PromiseFlatCString(aValue).get(),
211 nullptr);
213 return res ? NS_OK : NS_ERROR_FAILURE;
214 }
216 NS_IMETHODIMP
217 nsGConfService::SetInt(const nsACString &aKey, int32_t aValue)
218 {
219 bool res = gconf_client_set_int(mClient, PromiseFlatCString(aKey).get(),
220 aValue, nullptr);
222 return res ? NS_OK : NS_ERROR_FAILURE;
223 }
225 NS_IMETHODIMP
226 nsGConfService::SetFloat(const nsACString &aKey, float aValue)
227 {
228 bool res = gconf_client_set_float(mClient, PromiseFlatCString(aKey).get(),
229 aValue, nullptr);
231 return res ? NS_OK : NS_ERROR_FAILURE;
232 }
234 NS_IMETHODIMP
235 nsGConfService::GetAppForProtocol(const nsACString &aScheme, bool *aEnabled,
236 nsACString &aHandler)
237 {
238 nsAutoCString key("/desktop/gnome/url-handlers/");
239 key.Append(aScheme);
240 key.Append("/command");
242 GError *err = nullptr;
243 gchar *command = gconf_client_get_string(mClient, key.get(), &err);
244 if (!err && command) {
245 key.Replace(key.Length() - 7, 7, NS_LITERAL_CSTRING("enabled"));
246 *aEnabled = gconf_client_get_bool(mClient, key.get(), &err);
247 } else {
248 *aEnabled = false;
249 }
251 aHandler.Assign(command);
252 g_free(command);
254 if (err) {
255 g_error_free(err);
256 return NS_ERROR_FAILURE;
257 }
259 return NS_OK;
260 }
262 NS_IMETHODIMP
263 nsGConfService::HandlerRequiresTerminal(const nsACString &aScheme,
264 bool *aResult)
265 {
266 nsAutoCString key("/desktop/gnome/url-handlers/");
267 key.Append(aScheme);
268 key.Append("/requires_terminal");
270 GError *err = nullptr;
271 *aResult = gconf_client_get_bool(mClient, key.get(), &err);
272 if (err) {
273 g_error_free(err);
274 return NS_ERROR_FAILURE;
275 }
277 return NS_OK;
278 }
280 NS_IMETHODIMP
281 nsGConfService::SetAppForProtocol(const nsACString &aScheme,
282 const nsACString &aCommand)
283 {
284 nsAutoCString key("/desktop/gnome/url-handlers/");
285 key.Append(aScheme);
286 key.Append("/command");
288 bool res = gconf_client_set_string(mClient, key.get(),
289 PromiseFlatCString(aCommand).get(),
290 nullptr);
291 if (res) {
292 key.Replace(key.Length() - 7, 7, NS_LITERAL_CSTRING("enabled"));
293 res = gconf_client_set_bool(mClient, key.get(), true, nullptr);
294 if (res) {
295 key.Replace(key.Length() - 7, 7, NS_LITERAL_CSTRING("needs_terminal"));
296 res = gconf_client_set_bool(mClient, key.get(), false, nullptr);
297 if (res) {
298 key.Replace(key.Length() - 14, 14, NS_LITERAL_CSTRING("command-id"));
299 res = gconf_client_unset(mClient, key.get(), nullptr);
300 }
301 }
302 }
304 return res ? NS_OK : NS_ERROR_FAILURE;
305 }