1
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
3
* Copyright (C) 1999, 2000, 2000 Red Hat Inc.
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Library General Public
7
* License as published by the Free Software Foundation; either
8
* version 2 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Library General Public License for more details.
15
* You should have received a copy of the GNU Library General Public
16
* License along with this library; if not, write to the
17
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18
* Boston, MA 02111-1307, USA.
22
#include "gconf-client.h"
23
#include <gtk/gtksignal.h>
24
#include <gtk/gtktypeutils.h>
25
#include <gconf/gconf-internals.h>
28
* Error handler override
31
static GConfClientErrorHandlerFunc global_error_handler = NULL;
34
gconf_client_set_global_default_error_handler(GConfClientErrorHandlerFunc func)
36
global_error_handler = func;
43
typedef struct _CacheEntry CacheEntry;
47
/* Whether "value" was a default from a schema; i.e.
48
if this is TRUE, then value wasn't set, we just used
51
guint is_writable : 1;
54
static CacheEntry* cache_entry_new(GConfValue* val,
56
gboolean is_writable);
57
static void cache_entry_destroy(CacheEntry* ce);
60
* Dir object (for list of directories we're watching)
63
typedef struct _Dir Dir;
68
/* number of times this dir has been added */
72
static Dir* dir_new(const gchar* name, guint notify_id);
73
static void dir_destroy(Dir* d);
79
typedef struct _Listener Listener;
82
GConfClientNotifyFunc func;
84
GFreeFunc destroy_notify;
87
static Listener* listener_new(GConfClientNotifyFunc func,
88
GFreeFunc destroy_notify,
91
static void listener_destroy(Listener* l);
105
static void register_client (GConfClient *client);
106
static GConfClient *lookup_client (GConfEngine *engine);
107
static void unregister_client (GConfClient *client);
109
static void gconf_client_class_init (GConfClientClass *klass);
110
static void gconf_client_init (GConfClient *client);
111
static void gconf_client_real_unreturned_error (GConfClient* client, GError* error);
112
static void gconf_client_real_error (GConfClient* client, GError* error);
113
static void gconf_client_finalize (GtkObject* object);
115
static void gconf_client_cache (GConfClient* client,
118
gboolean is_writable,
119
GConfValue* value); /* takes ownership of value */
121
static gboolean gconf_client_lookup (GConfClient* client,
123
gboolean use_default,
124
gboolean* is_default,
125
gboolean* is_writable,
128
static void gconf_client_real_remove_dir (GConfClient* client,
132
static GConfValue* get (GConfClient *client,
134
gboolean use_default,
135
gboolean *is_default_retloc,
136
gboolean *is_writable_retloc,
140
static guint client_signals[LAST_SIGNAL] = { 0 };
141
static GtkObjectClass* parent_class = NULL;
144
gconf_client_get_type (void)
146
static GtkType client_type = 0;
150
static const GtkTypeInfo client_info =
153
sizeof (GConfClient),
154
sizeof (GConfClientClass),
155
(GtkClassInitFunc) gconf_client_class_init,
156
(GtkObjectInitFunc) gconf_client_init,
157
/* reserved_1 */ NULL,
158
/* reserved_2 */ NULL,
159
(GtkClassInitFunc) NULL,
162
client_type = gtk_type_unique (GTK_TYPE_OBJECT, &client_info);
169
gconf_client_class_init (GConfClientClass *class)
171
GtkObjectClass *object_class;
173
object_class = (GtkObjectClass*) class;
175
parent_class = gtk_type_class (gtk_object_get_type ());
177
client_signals[VALUE_CHANGED] =
178
gtk_signal_new ("value_changed",
181
GTK_SIGNAL_OFFSET (GConfClientClass, value_changed),
182
gtk_marshal_NONE__POINTER_POINTER,
183
GTK_TYPE_NONE, 2, GTK_TYPE_POINTER, GTK_TYPE_POINTER);
185
client_signals[UNRETURNED_ERROR] =
186
gtk_signal_new ("unreturned_error",
189
GTK_SIGNAL_OFFSET (GConfClientClass, unreturned_error),
190
gtk_marshal_NONE__POINTER,
191
GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
193
client_signals[ERROR] =
194
gtk_signal_new ("error",
197
GTK_SIGNAL_OFFSET (GConfClientClass, error),
198
gtk_marshal_NONE__POINTER,
199
GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
201
gtk_object_class_add_signals (object_class, client_signals, LAST_SIGNAL);
203
class->value_changed = NULL;
204
class->unreturned_error = gconf_client_real_unreturned_error;
205
class->error = gconf_client_real_error;
207
object_class->finalize = gconf_client_finalize;
211
gconf_client_init (GConfClient *client)
213
client->engine = NULL;
214
client->error_mode = GCONF_CLIENT_HANDLE_UNRETURNED;
215
client->dir_hash = g_hash_table_new(g_str_hash, g_str_equal);
216
client->cache_hash = g_hash_table_new(g_str_hash, g_str_equal);
217
/* We create the listeners only if they're actually used */
218
client->listeners = NULL;
222
destroy_dir_foreach_remove(gpointer key, gpointer value, gpointer user_data)
224
GConfClient *client = user_data;
227
/* remove notify for this dir */
229
if(d->notify_id != 0)
230
gconf_engine_notify_remove(client->engine, d->notify_id);
239
gconf_client_finalize (GtkObject* object)
241
GConfClient* client = GCONF_CLIENT(object);
243
g_hash_table_foreach_remove(client->dir_hash,
244
destroy_dir_foreach_remove, client);
246
gconf_client_clear_cache(client);
248
if (client->listeners != NULL)
250
gconf_listeners_free(client->listeners);
251
client->listeners = NULL;
254
g_hash_table_destroy(client->dir_hash);
255
client->dir_hash = NULL;
257
g_hash_table_destroy(client->cache_hash);
258
client->cache_hash = NULL;
260
unregister_client (client);
262
if (client->engine != NULL)
264
gconf_engine_unref(client->engine);
265
client->engine = NULL;
268
if (parent_class->finalize)
269
(*parent_class->finalize)(object);
273
* Default error handlers
277
gconf_client_real_unreturned_error (GConfClient* client, GError* error)
279
if (client->error_mode == GCONF_CLIENT_HANDLE_UNRETURNED)
281
if (global_error_handler != NULL)
283
(*global_error_handler) (client, error);
287
fprintf (stderr, _("GConf Error: %s\n"),
294
gconf_client_real_error (GConfClient* client, GError* error)
296
if (client->error_mode == GCONF_CLIENT_HANDLE_ALL)
298
if (global_error_handler != NULL)
300
(*global_error_handler) (client, error);
304
fprintf (stderr, _("GConf Error: %s\n"),
310
/* Emit the proper signals for the error, and fill in err */
312
handle_error(GConfClient* client, GError* error, GError** err)
316
gconf_client_error(client, error);
320
gconf_client_unreturned_error(client, error);
333
struct client_and_val {
339
notify_listeners_callback(GConfListeners* listeners,
342
gpointer listener_data,
345
struct client_and_val* cav = user_data;
346
Listener* l = listener_data;
348
g_return_if_fail(cav != NULL);
349
g_return_if_fail(cav->client != NULL);
350
g_return_if_fail(GCONF_IS_CLIENT(cav->client));
351
g_return_if_fail(l != NULL);
352
g_return_if_fail(l->func != NULL);
354
(*l->func)(cav->client, cnxn_id, cav->entry, l->data);
358
notify_from_server_callback(GConfEngine* conf, guint cnxn_id,
362
GConfClient* client = user_data;
364
g_return_if_fail(client != NULL);
365
g_return_if_fail(GCONF_IS_CLIENT(client));
366
g_return_if_fail(client->engine == conf);
368
/* First do the caching, so that state is sane for the
369
* listeners or functions connected to value_changed.
370
* We know this key is under a directory in our dir list.
372
gconf_client_cache(client,
376
entry->value ? gconf_value_copy(entry->value) : NULL);
378
/* Emit the value_changed signal before notifying specific listeners;
379
* I'm not sure there's a reason this matters though
381
gconf_client_value_changed(client,
385
/* Now notify our listeners, if any */
386
if (client->listeners != NULL)
388
struct client_and_val cav;
393
gconf_listeners_notify(client->listeners,
395
notify_listeners_callback,
405
gconf_client_get_default (void)
410
g_return_val_if_fail(gconf_is_initialized(), NULL);
412
engine = gconf_engine_get_default ();
414
client = lookup_client (engine);
417
g_assert (client->engine == engine);
418
gtk_object_ref (GTK_OBJECT (client));
419
gconf_engine_unref (engine);
424
client = gtk_type_new (gconf_client_get_type ());
426
/* Emulate GObject */
427
gtk_object_ref (GTK_OBJECT (client));
428
gtk_object_sink (GTK_OBJECT (client));
430
client->engine = engine;
431
register_client (client);
438
gconf_client_get_for_engine (GConfEngine* engine)
442
g_return_val_if_fail(gconf_is_initialized(), NULL);
444
client = lookup_client (engine);
447
g_assert (client->engine == engine);
448
gtk_object_ref (GTK_OBJECT (client));
453
client = gtk_type_new (gconf_client_get_type ());
455
/* Emulate GObject */
456
gtk_object_ref (GTK_OBJECT (client));
457
gtk_object_sink (GTK_OBJECT (client));
459
client->engine = engine;
461
gconf_engine_ref(client->engine);
463
register_client (client);
476
foreach_setup_overlap(gpointer key, gpointer value, gpointer user_data)
480
OverlapData * od = user_data;
484
/* if we have found the first (well there is only one anyway) directory
485
* that includes us that has a notify handler
487
#ifdef GCONF_ENABLE_DEBUG
488
if (dir->notify_id != 0 &&
489
gconf_key_is_below(dir->name, od->dirname))
491
g_assert(od->lower_dir == NULL);
495
if (od->lower_dir == NULL &&
496
dir->notify_id != 0 &&
497
gconf_key_is_below(dir->name, od->dirname))
500
/* if we have found a directory that we include and it has
501
* a notify_id, remove the notify handler now
502
* FIXME: this is a race, from now on we can miss notifies, it is
503
* not an incredible amount of time so this is not a showstopper */
504
else if (dir->notify_id != 0 &&
505
gconf_key_is_below (od->dirname, dir->name))
507
gconf_engine_notify_remove (client->engine, dir->notify_id);
513
setup_overlaps(GConfClient* client, const gchar* dirname)
519
od.dirname = dirname;
521
g_hash_table_foreach(client->dir_hash, foreach_setup_overlap, &od);
527
gconf_client_add_dir (GConfClient* client,
528
const gchar* dirname,
529
GConfClientPreloadType preload,
534
GError* error = NULL;
536
g_return_if_fail(gconf_valid_key(dirname, NULL));
538
d = g_hash_table_lookup (client->dir_hash, dirname);
544
overlap_dir = setup_overlaps (client, dirname);
546
/* only if there is no directory that includes us
547
* already add a notify
549
if (overlap_dir == NULL)
552
notify_id = gconf_engine_notify_add (client->engine,
554
notify_from_server_callback,
558
/* We got a notify ID or we got an error, not both */
559
g_return_if_fail( (notify_id != 0 && error == NULL) ||
560
(notify_id == 0 && error != NULL) );
563
if (handle_error(client, error, err))
566
g_assert(error == NULL);
573
d = dir_new(dirname, notify_id);
575
g_hash_table_insert(client->dir_hash, d->name, d);
577
gconf_client_preload(client, dirname, preload, &error);
579
handle_error(client, error, err);
593
foreach_add_notifies(gpointer key, gpointer value, gpointer user_data)
595
AddNotifiesData *ad = user_data;
601
if (ad->error != NULL)
604
if (dir->notify_id == 0)
607
overlap_dir = setup_overlaps(client, dir->name);
609
/* only if there is no directory that includes us
610
* already add a notify */
611
if (overlap_dir == NULL)
613
dir->notify_id = gconf_engine_notify_add(client->engine,
615
notify_from_server_callback,
619
/* We got a notify ID or we got an error, not both */
620
g_return_if_fail( (dir->notify_id != 0 && ad->error == NULL) ||
621
(dir->notify_id == 0 && ad->error != NULL) );
623
/* if error is returned, then we'll just ignore
624
* things until the end */
630
gconf_client_real_remove_dir (GConfClient* client,
636
g_return_if_fail(d != NULL);
637
g_return_if_fail(d->add_count == 0);
639
g_hash_table_remove(client->dir_hash, d->name);
641
/* remove notify for this dir */
643
if (d->notify_id != 0)
644
gconf_engine_notify_remove(client->engine, d->notify_id);
652
g_hash_table_foreach(client->dir_hash, foreach_add_notifies, &ad);
654
handle_error(client, ad.error, err);
658
gconf_client_remove_dir (GConfClient* client,
659
const gchar* dirname,
664
found = g_hash_table_lookup(client->dir_hash,
669
g_return_if_fail(found->add_count > 0);
671
found->add_count -= 1;
673
if (found->add_count == 0)
674
gconf_client_real_remove_dir(client, found, err);
676
#ifndef G_DISABLE_CHECKS
678
g_warning("Directory `%s' was not being monitored by GConfClient %p",
685
gconf_client_notify_add(GConfClient* client,
686
const gchar* namespace_section,
687
GConfClientNotifyFunc func,
689
GFreeFunc destroy_notify,
694
g_return_val_if_fail(client != NULL, 0);
695
g_return_val_if_fail(GCONF_IS_CLIENT(client), 0);
697
if (client->listeners == NULL)
698
client->listeners = gconf_listeners_new();
700
cnxn_id = gconf_listeners_add (client->listeners,
702
listener_new (func, destroy_notify, user_data),
703
(GFreeFunc)listener_destroy);
709
gconf_client_notify_remove (GConfClient* client,
712
g_return_if_fail(client != NULL);
713
g_return_if_fail(GCONF_IS_CLIENT(client));
714
g_return_if_fail(client->listeners != NULL);
716
gconf_listeners_remove(client->listeners, cnxn);
718
if (gconf_listeners_count(client->listeners) == 0)
720
gconf_listeners_free(client->listeners);
721
client->listeners = NULL;
726
gconf_client_set_error_handling(GConfClient* client,
727
GConfClientErrorHandlingMode mode)
729
g_return_if_fail(client != NULL);
730
g_return_if_fail(GCONF_IS_CLIENT(client));
732
client->error_mode = mode;
736
clear_cache_foreach(gchar* key, CacheEntry* ce, GConfClient* client)
739
cache_entry_destroy(ce);
745
gconf_client_clear_cache(GConfClient* client)
747
g_return_if_fail(client != NULL);
748
g_return_if_fail(GCONF_IS_CLIENT(client));
750
g_hash_table_foreach_remove(client->cache_hash, (GHRFunc)clear_cache_foreach,
753
g_assert(g_hash_table_size(client->cache_hash) == 0);
757
cache_pairs_in_dir(GConfClient* client, const gchar* path);
760
recurse_subdir_list(GConfClient* client, GSList* subdirs, const gchar* parent)
768
gchar* s = tmp->data;
769
gchar* full = gconf_concat_dir_and_key(parent, s);
771
cache_pairs_in_dir(client, full);
773
recurse_subdir_list(client, gconf_engine_all_dirs(client->engine, full, NULL), full);
778
tmp = g_slist_next(tmp);
781
g_slist_free(subdirs);
785
cache_pairs_in_dir(GConfClient* client, const gchar* dir)
789
GError* error = NULL;
791
pairs = gconf_engine_all_entries(client->engine, dir, &error);
795
fprintf(stderr, _("GConf warning: failure listing pairs in `%s': %s"),
796
dir, error->message);
807
GConfEntry* pair = tmp->data;
809
gconf_client_cache(client,
810
gconf_entry_get_key (pair),
811
gconf_entry_get_is_default(pair),
812
gconf_entry_get_is_writable(pair),
813
gconf_entry_steal_value(pair));
815
gconf_entry_free(pair);
817
tmp = g_slist_next(tmp);
825
gconf_client_preload (GConfClient* client,
826
const gchar* dirname,
827
GConfClientPreloadType type,
831
g_return_if_fail(client != NULL);
832
g_return_if_fail(GCONF_IS_CLIENT(client));
833
g_return_if_fail(dirname != NULL);
835
#ifdef GCONF_ENABLE_DEBUG
836
if (g_hash_table_lookup(client->dir_hash, dirname) == NULL)
838
g_warning("Can only preload directories you've added with gconf_client_add_dir()");
845
case GCONF_CLIENT_PRELOAD_NONE:
849
case GCONF_CLIENT_PRELOAD_ONELEVEL:
853
subdirs = gconf_engine_all_dirs(client->engine, dirname, NULL);
855
cache_pairs_in_dir(client, dirname);
859
case GCONF_CLIENT_PRELOAD_RECURSIVE:
863
subdirs = gconf_engine_all_dirs(client->engine, dirname, NULL);
865
cache_pairs_in_dir(client, dirname);
867
recurse_subdir_list(client, subdirs, dirname);
872
g_assert_not_reached();
878
* Basic key-manipulation facilities
882
gconf_client_set (GConfClient* client,
887
GError* error = NULL;
889
gconf_engine_set (client->engine, key, val, &error);
891
handle_error(client, error, err);
895
gconf_client_unset (GConfClient* client,
896
const gchar* key, GError** err)
898
GError* error = NULL;
900
gconf_engine_unset(client->engine, key, &error);
902
handle_error(client, error, err);
911
gconf_client_all_entries (GConfClient* client,
912
const gchar* dir, GError** err)
914
GError* error = NULL;
917
retval = gconf_engine_all_entries(client->engine, dir, &error);
919
handle_error(client, error, err);
925
gconf_client_all_dirs (GConfClient* client,
926
const gchar* dir, GError** err)
928
GError* error = NULL;
931
retval = gconf_engine_all_dirs(client->engine, dir, &error);
933
handle_error(client, error, err);
939
gconf_client_suggest_sync (GConfClient* client,
942
GError* error = NULL;
944
gconf_engine_suggest_sync(client->engine, &error);
946
handle_error(client, error, err);
950
gconf_client_dir_exists (GConfClient* client,
951
const gchar* dir, GError** err)
953
GError* error = NULL;
956
retval = gconf_engine_dir_exists(client->engine, dir, &error);
958
handle_error(client, error, err);
964
gconf_client_key_is_writable(GConfClient* client,
968
GError* error = NULL;
969
GConfValue* val = NULL;
970
gboolean is_writable = TRUE;
972
g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
974
val = get (client, key, TRUE,
975
NULL, &is_writable, &error);
977
if (val == NULL && error != NULL)
978
handle_error(client, error, err);
980
g_assert(error == NULL);
982
/* FIXME we could avoid creating this value at all if
983
* we were somewhat less lame.
986
gconf_value_free (val);
992
check_type(const gchar* key, GConfValue* val, GConfValueType t, GError** err)
996
gconf_set_error(err, GCONF_ERROR_TYPE_MISMATCH,
997
_("Expected `%s' got `%s' for key %s"),
998
gconf_value_type_to_string(t),
999
gconf_value_type_to_string(val->type),
1008
get (GConfClient *client,
1010
gboolean use_default,
1011
gboolean *is_default_retloc,
1012
gboolean *is_writable_retloc,
1015
GConfValue* val = NULL;
1016
gboolean is_default = FALSE;
1017
gboolean is_writable = TRUE;
1019
g_return_val_if_fail(client != NULL, NULL);
1020
g_return_val_if_fail(GCONF_IS_CLIENT(client), NULL);
1021
g_return_val_if_fail(error != NULL, NULL);
1022
g_return_val_if_fail(*error == NULL, NULL);
1024
/* Check our client-side cache */
1025
if (gconf_client_lookup(client, key, use_default,
1030
if (is_default_retloc)
1031
*is_default_retloc = is_default;
1033
if (is_writable_retloc)
1034
*is_writable_retloc = is_writable;
1036
/* may be NULL of course */
1037
return val ? gconf_value_copy (val) : NULL;
1040
g_assert(val == NULL); /* if it was in the cache we should have returned */
1042
/* Check the GConfEngine */
1043
val = gconf_engine_get_full(client->engine, key,
1044
gconf_current_locale(),
1045
use_default, &is_default, &is_writable,
1048
if (is_default_retloc)
1049
*is_default_retloc = is_default;
1051
if (is_writable_retloc)
1052
*is_writable_retloc = is_writable;
1056
g_return_val_if_fail(val == NULL, NULL);
1061
/* Cache this value, if it's in our directory list. FIXME could
1064
gchar* parent = g_strdup(key);
1067
end = strrchr(parent, '/');
1069
while (end && parent != end)
1073
if (g_hash_table_lookup(client->dir_hash, parent) != NULL)
1075
/* cache a copy of val */
1076
gconf_client_cache (client, key, is_default, is_writable,
1077
val ? gconf_value_copy (val) : NULL);
1081
end = strrchr(parent, '/');
1086
/* We don't own val, we're returning this copy belonging
1094
gconf_client_get_full (GConfClient* client,
1095
const gchar* key, const gchar* locale,
1096
gboolean use_schema_default,
1097
gboolean* value_is_default,
1098
gboolean* value_is_writable,
1101
GError* error = NULL;
1102
GConfValue* val = NULL;
1103
gboolean is_default = FALSE;
1104
gboolean is_writable = TRUE;
1106
g_return_val_if_fail(err == NULL || *err == NULL, NULL);
1109
g_warning("haven't implemented getting a specific locale in GConfClient");
1111
val = get(client, key, use_schema_default,
1112
&is_default, &is_writable, &error);
1114
if (val == NULL && error != NULL)
1115
handle_error(client, error, err);
1117
g_assert(error == NULL);
1120
if (value_is_default)
1121
*value_is_default = is_default;
1123
if (value_is_writable)
1124
*value_is_writable = is_writable;
1130
gconf_client_get_entry (GConfClient* client,
1132
const gchar* locale,
1133
gboolean use_schema_default,
1136
GError* error = NULL;
1137
GConfValue* val = NULL;
1138
gboolean is_default = FALSE;
1139
gboolean is_writable = TRUE;
1142
g_return_val_if_fail(err == NULL || *err == NULL, NULL);
1145
g_warning("haven't implemented getting a specific locale in GConfClient");
1147
val = get(client, key, use_schema_default,
1148
&is_default, &is_writable, &error);
1150
if (val == NULL && error != NULL)
1151
handle_error(client, error, err);
1153
g_assert(error == NULL);
1155
entry = gconf_entry_new_nocopy (g_strdup (key), val);
1156
entry->is_default = is_default;
1157
entry->is_writable = is_writable;
1163
gconf_client_get (GConfClient* client,
1167
return gconf_client_get_full(client, key, NULL, TRUE, NULL, NULL, err);
1171
gconf_client_get_without_default (GConfClient* client,
1175
return gconf_client_get_full(client, key, NULL, FALSE, NULL, NULL, err);
1179
gconf_client_get_default_from_schema (GConfClient* client,
1183
GError* error = NULL;
1184
GConfValue* val = NULL;
1185
gboolean is_default = FALSE;
1187
g_return_val_if_fail(err == NULL || *err == NULL, NULL);
1188
g_return_val_if_fail(client != NULL, NULL);
1189
g_return_val_if_fail(GCONF_IS_CLIENT(client), NULL);
1191
/* Check our client-side cache to see if the default is the same as
1192
the regular value (FIXME put a default_value field in the
1193
CacheEntry and store both, lose the is_default flag in CacheEntry) */
1194
if (gconf_client_lookup(client, key, TRUE,
1200
return val ? gconf_value_copy(val) : NULL;
1203
/* Check the GConfEngine */
1204
val = gconf_engine_get_default_from_schema(client->engine, key,
1209
g_assert(val == NULL);
1210
handle_error(client, error, err);
1215
/* FIXME eventually we'll cache the value
1216
by adding a field to CacheEntry */
1222
gconf_client_get_float (GConfClient* client, const gchar* key,
1225
static const gdouble def = 0.0;
1226
GError* error = NULL;
1229
g_return_val_if_fail(err == NULL || *err == NULL, 0.0);
1231
val = get(client, key, TRUE, NULL, NULL, &error);
1235
gdouble retval = def;
1237
g_assert(error == NULL);
1239
if (check_type(key, val, GCONF_VALUE_FLOAT, &error))
1240
retval = gconf_value_get_float(val);
1242
handle_error(client, error, err);
1244
gconf_value_free(val);
1251
handle_error(client, error, err);
1257
gconf_client_get_int (GConfClient* client, const gchar* key,
1260
static const gint def = 0;
1261
GError* error = NULL;
1264
g_return_val_if_fail(err == NULL || *err == NULL, 0);
1266
val = get(client, key, TRUE, NULL, NULL, &error);
1272
g_assert(error == NULL);
1274
if (check_type(key, val, GCONF_VALUE_INT, &error))
1275
retval = gconf_value_get_int(val);
1277
handle_error(client, error, err);
1279
gconf_value_free(val);
1286
handle_error(client, error, err);
1292
gconf_client_get_string(GConfClient* client, const gchar* key,
1295
static const gchar* def = NULL;
1296
GError* error = NULL;
1299
g_return_val_if_fail(err == NULL || *err == NULL, NULL);
1301
val = get(client, key, TRUE, NULL, NULL, &error);
1305
gchar* retval = NULL;
1307
g_assert(error == NULL);
1309
if (check_type(key, val, GCONF_VALUE_STRING, &error))
1310
/* we cheat here (look below) so we have to cast this */
1311
retval = (gchar *)gconf_value_get_string(val);
1313
handle_error(client, error, err);
1315
/* This is a cheat; don't copy */
1317
val->d.string_data = NULL; /* don't delete the string we are returning */
1319
retval = def ? g_strdup(def) : NULL;
1321
gconf_value_free(val);
1328
handle_error(client, error, err);
1329
return def ? g_strdup(def) : NULL;
1335
gconf_client_get_bool (GConfClient* client, const gchar* key,
1338
static const gboolean def = FALSE;
1339
GError* error = NULL;
1342
g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
1344
val = get(client, key, TRUE, NULL, NULL, &error);
1348
gboolean retval = def;
1350
g_assert(error == NULL);
1352
if (check_type(key, val, GCONF_VALUE_BOOL, &error))
1353
retval = gconf_value_get_bool(val);
1355
handle_error(client, error, err);
1357
gconf_value_free(val);
1364
handle_error(client, error, err);
1370
gconf_client_get_schema (GConfClient* client,
1371
const gchar* key, GError** err)
1373
GError* error = NULL;
1376
g_return_val_if_fail(err == NULL || *err == NULL, NULL);
1378
val = get(client, key, TRUE, NULL, NULL, &error);
1382
GConfSchema* retval = NULL;
1384
g_assert(error == NULL);
1386
if (check_type(key, val, GCONF_VALUE_SCHEMA, &error))
1387
retval = gconf_value_get_schema(val);
1389
handle_error(client, error, err);
1391
/* This is a cheat; don't copy */
1393
val->d.schema_data = NULL; /* don't delete the schema */
1395
gconf_value_free(val);
1402
handle_error(client, error, err);
1408
gconf_client_get_list (GConfClient* client, const gchar* key,
1409
GConfValueType list_type, GError** err)
1411
GError* error = NULL;
1414
g_return_val_if_fail(err == NULL || *err == NULL, NULL);
1416
val = get(client, key, TRUE, NULL, NULL, &error);
1422
g_assert(error == NULL);
1424
/* This function checks the type and destroys "val" */
1425
retval = gconf_value_list_to_primitive_list_destructive(val, list_type, &error);
1429
g_assert(retval == NULL);
1430
handle_error(client, error, err);
1439
handle_error(client, error, err);
1445
gconf_client_get_pair (GConfClient* client, const gchar* key,
1446
GConfValueType car_type, GConfValueType cdr_type,
1447
gpointer car_retloc, gpointer cdr_retloc,
1450
GError* error = NULL;
1453
g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
1455
val = get(client, key, TRUE, NULL, NULL, &error);
1459
g_assert(error == NULL);
1461
/* This function checks the type and destroys "val" */
1462
if (gconf_value_pair_to_primitive_pair_destructive(val, car_type, cdr_type,
1463
car_retloc, cdr_retloc,
1466
g_assert(error == NULL);
1471
g_assert(error != NULL);
1472
handle_error(client, error, err);
1480
handle_error(client, error, err);
1491
* For the set functions, we just set normally, and wait for the
1492
* notification to come back from the server before we update
1493
* our cache. This may be the wrong thing; maybe we should
1494
* update immediately?
1495
* Problem with delayed update: user calls set() then get(),
1496
* results in weirdness
1497
* Problem with with regular update: get() before the notify
1498
* is out of sync with the listening parts of the application
1500
* It is somewhat academic now anyway because the _set() call
1501
* won't return until all the notifications have happened, so the
1502
* notify signal will be emitted inside the set() call.
1506
gconf_client_set_float (GConfClient* client, const gchar* key,
1507
gdouble val, GError** err)
1509
GError* error = NULL;
1511
g_return_val_if_fail(client != NULL, FALSE);
1512
g_return_val_if_fail(GCONF_IS_CLIENT(client), FALSE);
1513
g_return_val_if_fail(key != NULL, FALSE);
1515
if (gconf_engine_set_float(client->engine, key, val, &error))
1519
handle_error(client, error, err);
1525
gconf_client_set_int (GConfClient* client, const gchar* key,
1526
gint val, GError** err)
1528
GError* error = NULL;
1530
g_return_val_if_fail(client != NULL, FALSE);
1531
g_return_val_if_fail(GCONF_IS_CLIENT(client), FALSE);
1532
g_return_val_if_fail(key != NULL, FALSE);
1534
if (gconf_engine_set_int(client->engine, key, val, &error))
1538
handle_error(client, error, err);
1544
gconf_client_set_string (GConfClient* client, const gchar* key,
1545
const gchar* val, GError** err)
1547
GError* error = NULL;
1549
g_return_val_if_fail(client != NULL, FALSE);
1550
g_return_val_if_fail(GCONF_IS_CLIENT(client), FALSE);
1551
g_return_val_if_fail(key != NULL, FALSE);
1552
g_return_val_if_fail(val != NULL, FALSE);
1554
if (gconf_engine_set_string(client->engine, key, val, &error))
1558
handle_error(client, error, err);
1564
gconf_client_set_bool (GConfClient* client, const gchar* key,
1565
gboolean val, GError** err)
1567
GError* error = NULL;
1569
g_return_val_if_fail(client != NULL, FALSE);
1570
g_return_val_if_fail(GCONF_IS_CLIENT(client), FALSE);
1571
g_return_val_if_fail(key != NULL, FALSE);
1573
if (gconf_engine_set_bool(client->engine, key, val, &error))
1577
handle_error(client, error, err);
1583
gconf_client_set_schema (GConfClient* client, const gchar* key,
1584
GConfSchema* val, GError** err)
1586
GError* error = NULL;
1588
g_return_val_if_fail(client != NULL, FALSE);
1589
g_return_val_if_fail(GCONF_IS_CLIENT(client), FALSE);
1590
g_return_val_if_fail(key != NULL, FALSE);
1591
g_return_val_if_fail(val != NULL, FALSE);
1593
if (gconf_engine_set_schema(client->engine, key, val, &error))
1597
handle_error(client, error, err);
1603
gconf_client_set_list (GConfClient* client, const gchar* key,
1604
GConfValueType list_type,
1608
GError* error = NULL;
1610
g_return_val_if_fail(client != NULL, FALSE);
1611
g_return_val_if_fail(GCONF_IS_CLIENT(client), FALSE);
1612
g_return_val_if_fail(key != NULL, FALSE);
1614
if (gconf_engine_set_list(client->engine, key, list_type, list, &error))
1618
handle_error(client, error, err);
1624
gconf_client_set_pair (GConfClient* client, const gchar* key,
1625
GConfValueType car_type, GConfValueType cdr_type,
1626
gconstpointer address_of_car,
1627
gconstpointer address_of_cdr,
1630
GError* error = NULL;
1632
g_return_val_if_fail(client != NULL, FALSE);
1633
g_return_val_if_fail(GCONF_IS_CLIENT(client), FALSE);
1634
g_return_val_if_fail(key != NULL, FALSE);
1636
if (gconf_engine_set_pair(client->engine, key, car_type, cdr_type,
1637
address_of_car, address_of_cdr, &error))
1641
handle_error(client, error, err);
1648
* Functions to emit signals
1652
gconf_client_error (GConfClient* client, GError* error)
1654
g_return_if_fail(client != NULL);
1655
g_return_if_fail(GCONF_IS_CLIENT(client));
1657
gtk_signal_emit(GTK_OBJECT(client), client_signals[ERROR], error);
1661
gconf_client_unreturned_error (GConfClient* client, GError* error)
1663
g_return_if_fail(client != NULL);
1664
g_return_if_fail(GCONF_IS_CLIENT(client));
1666
gtk_signal_emit(GTK_OBJECT(client), client_signals[UNRETURNED_ERROR], error);
1670
gconf_client_value_changed (GConfClient* client,
1674
g_return_if_fail(client != NULL);
1675
g_return_if_fail(GCONF_IS_CLIENT(client));
1676
g_return_if_fail(key != NULL);
1678
gtk_signal_emit(GTK_OBJECT(client), client_signals[VALUE_CHANGED],
1687
gconf_client_cache (GConfClient* client,
1689
gboolean is_default,
1690
gboolean is_writable,
1693
/* Remember: value may be NULL */
1695
gpointer oldkey = NULL, oldval = NULL;
1697
if (g_hash_table_lookup_extended(client->cache_hash, key, &oldkey, &oldval))
1699
/* Already have a value, update it */
1700
CacheEntry* ce = oldval;
1702
g_assert(ce != NULL);
1704
if (ce->value != NULL)
1705
gconf_value_free(ce->value);
1708
ce->is_default = is_default;
1709
ce->is_writable = is_writable;
1713
/* Create a new entry */
1714
CacheEntry* ce = cache_entry_new(value, is_default, is_writable);
1715
g_hash_table_insert(client->cache_hash, g_strdup(key), ce);
1720
gconf_client_lookup (GConfClient* client,
1722
gboolean use_default,
1723
gboolean* is_default,
1724
gboolean* is_writable,
1729
g_return_val_if_fail(valp != NULL, FALSE);
1730
g_return_val_if_fail(*valp == NULL, FALSE);
1732
ce = g_hash_table_lookup(client->cache_hash, key);
1747
*is_default = FALSE;
1753
*is_writable = ce->is_writable;
1767
cache_entry_new(GConfValue* val,
1768
gboolean is_default, gboolean is_writable)
1772
ce = g_new(CacheEntry, 1);
1774
/* val may be NULL */
1776
ce->is_default = is_default;
1777
ce->is_writable = is_writable;
1783
cache_entry_destroy(CacheEntry* ce)
1785
g_return_if_fail(ce != NULL);
1787
if (ce->value != NULL)
1788
gconf_value_free(ce->value);
1798
dir_new(const gchar* name, guint notify_id)
1804
d->name = g_strdup(name);
1805
d->notify_id = notify_id;
1814
g_return_if_fail(d != NULL);
1815
g_return_if_fail(d->notify_id == 0);
1826
listener_new(GConfClientNotifyFunc func,
1827
GFreeFunc destroy_notify,
1832
l = g_new(Listener, 1);
1836
l->destroy_notify = destroy_notify;
1842
listener_destroy(Listener* l)
1844
g_return_if_fail(l != NULL);
1846
if (l->destroy_notify)
1847
(* l->destroy_notify) (l->data);
1858
GConfClient* client;
1860
GSList* remove_list;
1861
gboolean remove_committed;
1865
commit_foreach (GConfChangeSet* cs,
1870
struct CommitData* cd = user_data;
1872
g_assert(cd != NULL);
1874
if (cd->error != NULL)
1878
gconf_client_set (cd->client, key, value, &cd->error);
1880
gconf_client_unset (cd->client, key, &cd->error);
1882
if (cd->error == NULL && cd->remove_committed)
1884
/* Bad bad bad; we keep the key reference, knowing that it's
1885
valid until we modify the change set, to avoid string copies. */
1886
cd->remove_list = g_slist_prepend(cd->remove_list, (gchar*)key);
1891
gconf_client_commit_change_set (GConfClient* client,
1893
gboolean remove_committed,
1896
struct CommitData cd;
1899
g_return_val_if_fail(client != NULL, FALSE);
1900
g_return_val_if_fail(GCONF_IS_CLIENT(client), FALSE);
1901
g_return_val_if_fail(cs != NULL, FALSE);
1902
g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
1906
cd.remove_list = NULL;
1907
cd.remove_committed = remove_committed;
1909
/* Because the commit could have lots of side
1910
effects, this makes it safer */
1911
gconf_change_set_ref(cs);
1912
gtk_object_ref(GTK_OBJECT(client));
1914
gconf_change_set_foreach(cs, commit_foreach, &cd);
1916
tmp = cd.remove_list;
1919
const gchar* key = tmp->data;
1921
gconf_change_set_remove(cs, key);
1923
/* key is now invalid due to our little evil trick */
1925
tmp = g_slist_next(tmp);
1928
g_slist_free(cd.remove_list);
1930
gconf_change_set_unref(cs);
1931
gtk_object_unref(GTK_OBJECT(client));
1933
if (cd.error != NULL)
1938
g_error_free(cd.error);
1944
g_assert((!remove_committed) ||
1945
(gconf_change_set_size(cs) == 0));
1952
GConfClient* client;
1954
GConfChangeSet* revert_set;
1958
revert_foreach (GConfChangeSet* cs,
1963
struct RevertData* rd = user_data;
1964
GConfValue* old_value;
1965
GError* error = NULL;
1967
g_assert(rd != NULL);
1969
if (rd->error != NULL)
1972
old_value = gconf_client_get_without_default(rd->client, key, &error);
1977
g_warning("error creating revert set: %s", error->message);
1978
g_error_free(error);
1982
if (old_value == NULL &&
1984
return; /* this commit will have no effect. */
1986
if (old_value == NULL)
1987
gconf_change_set_unset(rd->revert_set, key);
1989
gconf_change_set_set_nocopy(rd->revert_set, key, old_value);
1994
gconf_client_reverse_change_set (GConfClient* client,
1998
struct RevertData rd;
2002
rd.revert_set = gconf_change_set_new();
2004
/* we're emitting signals and such, avoid
2005
nasty side effects with these.
2007
gtk_object_ref(GTK_OBJECT(rd.client));
2008
gconf_change_set_ref(cs);
2010
gconf_change_set_foreach(cs, revert_foreach, &rd);
2012
if (rd.error != NULL)
2017
g_error_free(rd.error);
2020
gtk_object_unref(GTK_OBJECT(rd.client));
2021
gconf_change_set_unref(cs);
2023
return rd.revert_set;
2028
gconf_client_change_set_from_currentv (GConfClient* client,
2032
GConfValue* old_value;
2033
GConfChangeSet* new_set;
2036
g_return_val_if_fail(err == NULL || *err == NULL, NULL);
2038
new_set = gconf_change_set_new();
2042
while (*keyp != NULL)
2044
GError* error = NULL;
2045
const gchar* key = *keyp;
2047
old_value = gconf_client_get_without_default(client, key, &error);
2052
g_warning("error creating change set from current keys: %s", error->message);
2053
g_error_free(error);
2057
if (old_value == NULL)
2058
gconf_change_set_unset(new_set, key);
2060
gconf_change_set_set_nocopy(new_set, key, old_value);
2069
gconf_client_change_set_from_current (GConfClient* client,
2071
const gchar* first_key,
2074
GSList* keys = NULL;
2078
GConfChangeSet* retval;
2082
g_return_val_if_fail(err == NULL || *err == NULL, NULL);
2084
va_start (args, first_key);
2090
keys = g_slist_prepend(keys, (/*non-const*/gchar*)arg);
2092
arg = va_arg (args, const gchar*);
2097
vec = g_new0(const gchar*, g_slist_length(keys) + 1);
2107
tmp = g_slist_next(tmp);
2112
retval = gconf_client_change_set_from_currentv(client, vec, err);
2119
static GHashTable * clients = NULL;
2122
register_client (GConfClient *client)
2124
if (clients == NULL)
2125
clients = g_hash_table_new (NULL, NULL);
2127
g_hash_table_insert (clients, client->engine, client);
2130
static GConfClient *
2131
lookup_client (GConfEngine *engine)
2133
if (clients == NULL)
2136
return g_hash_table_lookup (clients, engine);
2140
unregister_client (GConfClient *client)
2142
g_return_if_fail (clients != NULL);
2144
g_hash_table_remove (clients, client->engine);