summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog31
-rw-r--r--gconf/gconf-changeset.c46
-rw-r--r--gconf/gconf-changeset.h9
-rw-r--r--gconf/gconf-client.c141
-rw-r--r--gconf/gconf-client.h20
-rw-r--r--gconf/gconf-internals.c354
-rw-r--r--gconf/gconf-internals.h23
-rw-r--r--gconf/gconf.c309
-rw-r--r--gconf/gconf.h1
-rw-r--r--wrappers/gtk/gconf-client.c141
-rw-r--r--wrappers/gtk/gconf-client.h20
11 files changed, 806 insertions, 289 deletions
diff --git a/ChangeLog b/ChangeLog
index 74ae552a..6bf65e7f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,34 @@
+1999-11-15 Havoc Pennington <hp@pobox.com>
+
+ * gconf/gconf.c (gconf_get): Fix it to use the current
+ locale as documented.
+
+ * gconf/gconf-internals.c
+ (gconf_value_list_to_primitive_list_destructive): new function
+ takes most code from gconf_get_list()
+ (gconf_value_pair_to_primitive_pair_destructive): new function
+
+ * wrappers/gtk/gconf-client.c (get): Return a copy of the cached
+ value, should save us some segfaults.
+ (gconf_client_get_list): new function
+ (gconf_client_get_pair): new function
+ (gconf_client_set_list): new function
+ (gconf_client_set_pair): new function
+
+ * gconf/gconf-internals.c (gconf_value_pair_from_primitive_pair):
+ new function removes guts of gconf_set_pair()
+
+ * gconf/gconf.c (gconf_set_list): change to use
+ gconf_value_list_from_primitive_list()
+
+ * gconf/gconf-changeset.c (gconf_change_set_set_list): new
+ convenience function
+ (gconf_change_set_set_pair): new function
+
+ * gconf/gconf-internals.c (gconf_value_list_from_primitive_list):
+ new function, takes most of the code from gconf_set_list() to
+ share with other list-set wrappers
+
1999-11-14 Havoc Pennington <hp@pobox.com>
* backends/xml-backend.c (listify_foreach): s/gconf_entry_new/gconf_entry_new_nocopy/
diff --git a/gconf/gconf-changeset.c b/gconf/gconf-changeset.c
index 87e418c5..d2567dd8 100644
--- a/gconf/gconf-changeset.c
+++ b/gconf/gconf-changeset.c
@@ -18,6 +18,7 @@
*/
#include "gconf-changeset.h"
+#include "gconf-internals.h"
typedef enum {
CHANGE_INVALID,
@@ -294,6 +295,51 @@ gconf_change_set_set_schema (GConfChangeSet* cs, const gchar* key,
gconf_change_set_set_nocopy(cs, key, value);
}
+void
+gconf_change_set_set_list (GConfChangeSet* cs, const gchar* key,
+ GConfValueType list_type,
+ GSList* list)
+{
+ GConfValue* value_list;
+
+ g_return_if_fail(cs != NULL);
+ g_return_if_fail(key != NULL);
+ g_return_if_fail(list_type != GCONF_VALUE_INVALID);
+ g_return_if_fail(list_type != GCONF_VALUE_LIST);
+ g_return_if_fail(list_type != GCONF_VALUE_PAIR);
+
+ value_list = gconf_value_list_from_primitive_list(list_type, list);
+
+ gconf_change_set_set_nocopy(cs, key, value_list);
+}
+
+
+void
+gconf_change_set_set_pair (GConfChangeSet* cs, const gchar* key,
+ GConfValueType car_type, GConfValueType cdr_type,
+ gconstpointer address_of_car,
+ gconstpointer address_of_cdr)
+{
+ GConfValue* pair;
+
+ g_return_if_fail(cs != NULL);
+ g_return_if_fail(key != NULL);
+ g_return_if_fail(car_type != GCONF_VALUE_INVALID);
+ g_return_if_fail(car_type != GCONF_VALUE_LIST);
+ g_return_if_fail(car_type != GCONF_VALUE_PAIR);
+ g_return_if_fail(cdr_type != GCONF_VALUE_INVALID);
+ g_return_if_fail(cdr_type != GCONF_VALUE_LIST);
+ g_return_if_fail(cdr_type != GCONF_VALUE_PAIR);
+ g_return_if_fail(address_of_car != NULL);
+ g_return_if_fail(address_of_cdr != NULL);
+
+ pair = gconf_value_pair_from_primitive_pair(car_type, cdr_type,
+ address_of_car, address_of_cdr);
+
+ gconf_change_set_set_nocopy(cs, key, pair);
+}
+
+
/*
* Change
*/
diff --git a/gconf/gconf-changeset.h b/gconf/gconf-changeset.h
index 6152f35a..0d60b46f 100644
--- a/gconf/gconf-changeset.h
+++ b/gconf/gconf-changeset.h
@@ -85,6 +85,15 @@ void gconf_change_set_set_bool (GConfChangeSet* cs, const gchar* key,
void gconf_change_set_set_schema (GConfChangeSet* cs, const gchar* key,
GConfSchema* val);
+void gconf_change_set_set_list (GConfChangeSet* cs, const gchar* key,
+ GConfValueType list_type,
+ GSList* list);
+
+void gconf_change_set_set_pair (GConfChangeSet* cs, const gchar* key,
+ GConfValueType car_type, GConfValueType cdr_type,
+ gconstpointer address_of_car,
+ gconstpointer address_of_cdr);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/gconf/gconf-client.c b/gconf/gconf-client.c
index 6e559fe4..131068b8 100644
--- a/gconf/gconf-client.c
+++ b/gconf/gconf-client.c
@@ -698,7 +698,7 @@ get(GConfClient* client, const gchar* key, GConfError** error)
/* Check our client-side cache */
if (gconf_client_lookup(client, key, &val))
- return val; /* stored in cache, not necessarily set though */
+ return gconf_value_copy(val); /* stored in cache, not necessarily set though */
g_assert(val == NULL); /* if it was in the cache we should have returned */
@@ -723,6 +723,7 @@ get(GConfClient* client, const gchar* key, GConfError** error)
if (gconf_key_is_below(d->name, key))
{
+ /* note that we cache a _copy_ */
gconf_client_cache(client, key,
val ? gconf_value_copy(val) : NULL);
break;
@@ -742,6 +743,8 @@ gconf_client_get_float (GConfClient* client, const gchar* key,
GConfError* error = NULL;
GConfValue* val;
+ g_return_val_if_fail(err == NULL || *err == NULL, 0.0);
+
val = get(client, key, &error);
if (val != NULL)
@@ -774,6 +777,8 @@ gconf_client_get_int (GConfClient* client, const gchar* key,
GConfError* error = NULL;
GConfValue* val;
+ g_return_val_if_fail(err == NULL || *err == NULL, 0);
+
val = get(client, key, &error);
if (val != NULL)
@@ -807,6 +812,8 @@ gconf_client_get_string(GConfClient* client, const gchar* key,
GConfError* error = NULL;
GConfValue* val;
+ g_return_val_if_fail(err == NULL || *err == NULL, NULL);
+
val = get(client, key, &error);
if (val != NULL)
@@ -846,6 +853,8 @@ gconf_client_get_bool (GConfClient* client, const gchar* key,
GConfError* error = NULL;
GConfValue* val;
+ g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
+
val = get(client, key, &error);
if (val != NULL)
@@ -878,6 +887,8 @@ gconf_client_get_schema (GConfClient* client,
GConfError* error = NULL;
GConfValue* val;
+ g_return_val_if_fail(err == NULL || *err == NULL, NULL);
+
val = get(client, key, &error);
if (val != NULL)
@@ -907,6 +918,89 @@ gconf_client_get_schema (GConfClient* client,
}
}
+GSList*
+gconf_client_get_list (GConfClient* client, const gchar* key,
+ GConfValueType list_type, GConfError** err)
+{
+ GConfError* error = NULL;
+ GConfValue* val;
+
+ g_return_val_if_fail(err == NULL || *err == NULL, NULL);
+
+ val = get(client, key, &error);
+
+ if (val != NULL)
+ {
+ GSList* retval;
+
+ g_assert(error == NULL);
+
+ /* This function checks the type and destroys "val" */
+ retval = gconf_value_list_to_primitive_list_destructive(val, list_type, &error);
+
+ if (error != NULL)
+ {
+ g_assert(retval == NULL);
+ handle_error(client, error, err);
+ return NULL;
+ }
+ else
+ return retval;
+ }
+ else
+ {
+ if (error != NULL)
+ handle_error(client, error, err);
+ return NULL;
+ }
+}
+
+gboolean
+gconf_client_get_pair (GConfClient* client, const gchar* key,
+ GConfValueType car_type, GConfValueType cdr_type,
+ gpointer car_retloc, gpointer cdr_retloc,
+ GConfError** err)
+{
+ GConfError* error = NULL;
+ GConfValue* val;
+
+ g_return_val_if_fail(err == NULL || *err == NULL, NULL);
+
+ val = get(client, key, &error);
+
+ if (val != NULL)
+ {
+ g_assert(error == NULL);
+
+ /* This function checks the type and destroys "val" */
+ if (gconf_value_pair_to_primitive_pair_destructive(val, car_type, cdr_type,
+ car_retloc, cdr_retloc,
+ &error))
+ {
+ g_assert(error == NULL);
+ return TRUE;
+ }
+ else
+ {
+ g_assert(error != NULL);
+ handle_error(client, error, err);
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (error != NULL)
+ {
+ handle_error(client, error, err);
+ return FALSE;
+ }
+ else
+ return TRUE;
+ }
+
+}
+
+
/*
* For the set functions, we just set normally, and wait for the
* notification to come back from the server before we update
@@ -1019,6 +1113,51 @@ gconf_client_set_schema (GConfClient* client, const gchar* key,
}
}
+gboolean
+gconf_client_set_list (GConfClient* client, const gchar* key,
+ GConfValueType list_type,
+ GSList* list,
+ GConfError** err)
+{
+ GConfError* error = NULL;
+
+ g_return_val_if_fail(client != NULL, FALSE);
+ g_return_val_if_fail(GCONF_IS_CLIENT(client), FALSE);
+ g_return_val_if_fail(key != NULL, FALSE);
+
+ if (gconf_set_list(client->engine, key, list_type, list, &error))
+ return TRUE;
+ else
+ {
+ handle_error(client, error, err);
+ return FALSE;
+ }
+}
+
+gboolean
+gconf_client_set_pair (GConfClient* client, const gchar* key,
+ GConfValueType car_type, GConfValueType cdr_type,
+ gconstpointer address_of_car,
+ gconstpointer address_of_cdr,
+ GConfError** err)
+{
+ GConfError* error = NULL;
+
+ g_return_val_if_fail(client != NULL, FALSE);
+ g_return_val_if_fail(GCONF_IS_CLIENT(client), FALSE);
+ g_return_val_if_fail(key != NULL, FALSE);
+
+ if (gconf_set_pair(client->engine, key, car_type, cdr_type,
+ address_of_car, address_of_car, &error))
+ return TRUE;
+ else
+ {
+ handle_error(client, error, err);
+ return FALSE;
+ }
+}
+
+
/*
* Functions to emit signals
*/
diff --git a/gconf/gconf-client.h b/gconf/gconf-client.h
index 68857ecc..311033a6 100644
--- a/gconf/gconf-client.h
+++ b/gconf/gconf-client.h
@@ -279,6 +279,14 @@ gboolean gconf_client_get_bool (GConfClient* client, const gchar* key,
GConfSchema* gconf_client_get_schema (GConfClient* client,
const gchar* key, GConfError** err);
+GSList* gconf_client_get_list (GConfClient* client, const gchar* key,
+ GConfValueType list_type, GConfError** err);
+
+gboolean gconf_client_get_pair (GConfClient* client, const gchar* key,
+ GConfValueType car_type, GConfValueType cdr_type,
+ gpointer car_retloc, gpointer cdr_retloc,
+ GConfError** err);
+
/* No convenience functions for lists or pairs, since there are too
many combinations of types possible
*/
@@ -300,6 +308,18 @@ gboolean gconf_client_set_bool (GConfClient* client, const gchar* key,
gboolean gconf_client_set_schema (GConfClient* client, const gchar* key,
GConfSchema* val, GConfError** err);
+/* List should be the same as the one gconf_client_get_list() would return */
+gboolean gconf_client_set_list (GConfClient* client, const gchar* key,
+ GConfValueType list_type,
+ GSList* list,
+ GConfError** err);
+
+gboolean gconf_client_set_pair (GConfClient* client, const gchar* key,
+ GConfValueType car_type, GConfValueType cdr_type,
+ gconstpointer address_of_car,
+ gconstpointer address_of_cdr,
+ GConfError** err);
+
/*
* Functions to emit signals
*/
diff --git a/gconf/gconf-internals.c b/gconf/gconf-internals.c
index d6b617d2..bf7981f1 100644
--- a/gconf/gconf-internals.c
+++ b/gconf/gconf-internals.c
@@ -1020,3 +1020,357 @@ gconf_log(GConfLogPriority pri, const gchar* fmt, ...)
g_free(msg);
}
+
+/*
+ * List/pair conversion
+ */
+
+GConfValue*
+gconf_value_list_from_primitive_list(GConfValueType list_type, GSList* list)
+{
+ GSList* value_list;
+ GSList* tmp;
+
+ g_return_val_if_fail(list_type != GCONF_VALUE_INVALID, NULL);
+ g_return_val_if_fail(list_type != GCONF_VALUE_LIST, NULL);
+ g_return_val_if_fail(list_type != GCONF_VALUE_PAIR, NULL);
+
+ value_list = NULL;
+
+ tmp = list;
+
+ while (tmp != NULL)
+ {
+ GConfValue* val;
+
+ val = gconf_value_new(list_type);
+
+ switch (list_type)
+ {
+ case GCONF_VALUE_INT:
+ gconf_value_set_int(val, GPOINTER_TO_INT(tmp->data));
+ break;
+
+ case GCONF_VALUE_BOOL:
+ gconf_value_set_bool(val, GPOINTER_TO_INT(tmp->data));
+ break;
+
+ case GCONF_VALUE_FLOAT:
+ gconf_value_set_float(val, *((gdouble*)tmp->data));
+ break;
+
+ case GCONF_VALUE_STRING:
+ gconf_value_set_string(val, tmp->data);
+ break;
+
+ case GCONF_VALUE_SCHEMA:
+ gconf_value_set_schema(val, tmp->data);
+ break;
+
+ default:
+ g_assert_not_reached();
+ break;
+ }
+
+ value_list = g_slist_prepend(value_list, val);
+
+ tmp = g_slist_next(tmp);
+ }
+
+ /* Get it in the right order. */
+ value_list = g_slist_reverse(value_list);
+
+ {
+ GConfValue* value_with_list;
+
+ value_with_list = gconf_value_new(GCONF_VALUE_LIST);
+ gconf_value_set_list_type(value_with_list, list_type);
+ gconf_value_set_list_nocopy(value_with_list, value_list);
+
+ return value_with_list;
+ }
+}
+
+
+static GConfValue*
+from_primitive(GConfValueType type, gconstpointer address)
+{
+ GConfValue* val;
+
+ val = gconf_value_new(type);
+
+ switch (type)
+ {
+ case GCONF_VALUE_INT:
+ gconf_value_set_int(val, *((const gint*)address));
+ break;
+
+ case GCONF_VALUE_BOOL:
+ gconf_value_set_bool(val, *((const gboolean*)address));
+ break;
+
+ case GCONF_VALUE_STRING:
+ gconf_value_set_string(val, *((const gchar**)address));
+ break;
+
+ case GCONF_VALUE_FLOAT:
+ gconf_value_set_float(val, *((const gdouble*)address));
+ break;
+
+ case GCONF_VALUE_SCHEMA:
+ gconf_value_set_schema(val, *((GConfSchema**)address));
+ break;
+
+ default:
+ g_assert_not_reached();
+ break;
+ }
+
+ return val;
+}
+
+GConfValue*
+gconf_value_pair_from_primitive_pair(GConfValueType car_type,
+ GConfValueType cdr_type,
+ gconstpointer address_of_car,
+ gconstpointer address_of_cdr)
+{
+ GConfValue* pair;
+ GConfValue* car;
+ GConfValue* cdr;
+
+ g_return_val_if_fail(car_type != GCONF_VALUE_INVALID, NULL);
+ g_return_val_if_fail(car_type != GCONF_VALUE_LIST, NULL);
+ g_return_val_if_fail(car_type != GCONF_VALUE_PAIR, NULL);
+ g_return_val_if_fail(cdr_type != GCONF_VALUE_INVALID, NULL);
+ g_return_val_if_fail(cdr_type != GCONF_VALUE_LIST, NULL);
+ g_return_val_if_fail(cdr_type != GCONF_VALUE_PAIR, NULL);
+ g_return_val_if_fail(address_of_car != NULL, NULL);
+ g_return_val_if_fail(address_of_cdr != NULL, NULL);
+
+ car = from_primitive(car_type, address_of_car);
+ cdr = from_primitive(cdr_type, address_of_cdr);
+
+ pair = gconf_value_new(GCONF_VALUE_PAIR);
+ gconf_value_set_car_nocopy(pair, car);
+ gconf_value_set_cdr_nocopy(pair, cdr);
+
+ return pair;
+}
+
+
+GSList*
+gconf_value_list_to_primitive_list_destructive(GConfValue* val,
+ GConfValueType list_type,
+ GConfError** err)
+{
+ GSList* retval;
+
+ g_return_val_if_fail(val != NULL, NULL);
+ g_return_val_if_fail(list_type != GCONF_VALUE_INVALID, NULL);
+ g_return_val_if_fail(list_type != GCONF_VALUE_LIST, NULL);
+ g_return_val_if_fail(list_type != GCONF_VALUE_PAIR, NULL);
+ g_return_val_if_fail(err == NULL || *err == NULL, NULL);
+
+ if (val->type != GCONF_VALUE_LIST)
+ {
+ if (err)
+ *err = gconf_error_new(GCONF_TYPE_MISMATCH,
+ _("Expected list, got %s"),
+ gconf_value_type_to_string(val->type));
+ gconf_value_destroy(val);
+ return NULL;
+ }
+
+ if (gconf_value_list_type(val) != list_type)
+ {
+ if (err)
+ *err = gconf_error_new(GCONF_TYPE_MISMATCH,
+ _("Expected list of %s, got list of %s"),
+ gconf_value_type_to_string(list_type),
+ gconf_value_type_to_string(val->type));
+ gconf_value_destroy(val);
+ return NULL;
+ }
+
+ g_assert(gconf_value_list_type(val) == list_type);
+
+ retval = gconf_value_list(val);
+
+ /* Cheating the API to avoid a list copy; set this to NULL to
+ avoid destroying the list */
+ val->d.list_data.list = NULL;
+
+ gconf_value_destroy(val);
+ val = NULL;
+
+ {
+ /* map (typeChange, retval) */
+ GSList* tmp;
+
+ tmp = retval;
+
+ while (tmp != NULL)
+ {
+ GConfValue* elem = tmp->data;
+
+ g_assert(elem != NULL);
+ g_assert(elem->type == list_type);
+
+ switch (list_type)
+ {
+ case GCONF_VALUE_INT:
+ case GCONF_VALUE_BOOL:
+ tmp->data = GINT_TO_POINTER(gconf_value_int(elem));
+ break;
+
+ case GCONF_VALUE_FLOAT:
+ {
+ gdouble* d = g_new(gdouble, 1);
+ *d = gconf_value_float(elem);
+ tmp->data = d;
+ }
+ break;
+
+ case GCONF_VALUE_STRING:
+ {
+ /* Cheat again, and steal the string from the value */
+ tmp->data = elem->d.string_data;
+ elem->d.string_data = NULL;
+ }
+ break;
+
+ case GCONF_VALUE_SCHEMA:
+ {
+ /* and also steal the schema... */
+ tmp->data = elem->d.schema_data;
+ elem->d.schema_data = NULL;
+ }
+ break;
+
+ default:
+ g_assert_not_reached();
+ break;
+ }
+
+ /* Clean up the value */
+ gconf_value_destroy(elem);
+
+ tmp = g_slist_next(tmp);
+ }
+ } /* list conversion block */
+
+ return retval;
+}
+
+
+static void
+primitive_value(gpointer retloc, GConfValue* val)
+{
+ switch (val->type)
+ {
+ case GCONF_VALUE_INT:
+ *((gint*)retloc) = gconf_value_int(val);
+ break;
+
+ case GCONF_VALUE_FLOAT:
+ *((gdouble*)retloc) = gconf_value_float(val);
+ break;
+
+ case GCONF_VALUE_STRING:
+ {
+ *((gchar**)retloc) = val->d.string_data;
+ /* cheat and steal the string to avoid a copy */
+ val->d.string_data = NULL;
+ }
+ break;
+
+ case GCONF_VALUE_BOOL:
+ *((gboolean*)retloc) = gconf_value_bool(val);
+ break;
+
+ case GCONF_VALUE_SCHEMA:
+ *((GConfSchema**)retloc) = gconf_value_schema(val);
+ break;
+
+ default:
+ g_assert_not_reached();
+ break;
+ }
+}
+
+gboolean
+gconf_value_pair_to_primitive_pair_destructive(GConfValue* val,
+ GConfValueType car_type,
+ GConfValueType cdr_type,
+ gpointer car_retloc,
+ gpointer cdr_retloc,
+ GConfError** err)
+{
+ GConfValue* car;
+ GConfValue* cdr;
+
+ g_return_val_if_fail(val != NULL, FALSE);
+ g_return_val_if_fail(car_type != GCONF_VALUE_INVALID, FALSE);
+ g_return_val_if_fail(car_type != GCONF_VALUE_LIST, FALSE);
+ g_return_val_if_fail(car_type != GCONF_VALUE_PAIR, FALSE);
+ g_return_val_if_fail(cdr_type != GCONF_VALUE_INVALID, FALSE);
+ g_return_val_if_fail(cdr_type != GCONF_VALUE_LIST, FALSE);
+ g_return_val_if_fail(cdr_type != GCONF_VALUE_PAIR, FALSE);
+ g_return_val_if_fail(car_retloc != NULL, FALSE);
+ g_return_val_if_fail(cdr_retloc != NULL, FALSE);
+ g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
+
+ if (val->type != GCONF_VALUE_PAIR)
+ {
+ if (err)
+ *err = gconf_error_new(GCONF_TYPE_MISMATCH,
+ _("Expected pair, got %s"),
+ gconf_value_type_to_string(val->type));
+ gconf_value_destroy(val);
+ return FALSE;
+ }
+
+ car = gconf_value_car(val);
+ cdr = gconf_value_cdr(val);
+
+ if (car == NULL ||
+ cdr == NULL)
+ {
+ if (err)
+ *err = gconf_error_new(GCONF_TYPE_MISMATCH,
+ _("Expected (%s,%s) pair, got a pair with one or both values missing"),
+ gconf_value_type_to_string(car_type),
+ gconf_value_type_to_string(cdr_type));
+
+ gconf_value_destroy(val);
+ return FALSE;
+ }
+
+ g_assert(car != NULL);
+ g_assert(cdr != NULL);
+
+ if (car->type != car_type ||
+ cdr->type != cdr_type)
+ {
+ if (err)
+ *err = gconf_error_new(GCONF_TYPE_MISMATCH,
+ _("Expected pair of type (%s,%s) got type (%s,%s)"),
+ gconf_value_type_to_string(car_type),
+ gconf_value_type_to_string(cdr_type),
+ gconf_value_type_to_string(car->type),
+ gconf_value_type_to_string(cdr->type));
+ gconf_value_destroy(val);
+ return FALSE;
+ }
+
+ primitive_value(car_retloc, car);
+ primitive_value(cdr_retloc, cdr);
+
+ gconf_value_destroy(val);
+
+ return TRUE;
+}
+
+
+
diff --git a/gconf/gconf-internals.h b/gconf/gconf-internals.h
index e34468f0..c6b6aeb7 100644
--- a/gconf/gconf-internals.h
+++ b/gconf/gconf-internals.h
@@ -103,6 +103,29 @@ GConfValue* gconf_value_new_pair_from_string (GConfValueType car_type,
GConfValueType cdr_type,
const gchar* str);
+/*
+ * List/pair conversion stuff
+ */
+
+GConfValue* gconf_value_list_from_primitive_list(GConfValueType list_type, GSList* list);
+
+GConfValue* gconf_value_pair_from_primitive_pair(GConfValueType car_type,
+ GConfValueType cdr_type,
+ gconstpointer address_of_car,
+ gconstpointer address_of_cdr);
+
+
+GSList* gconf_value_list_to_primitive_list_destructive(GConfValue* val,
+ GConfValueType list_type,
+ GConfError** err);
+
+gboolean gconf_value_pair_to_primitive_pair_destructive(GConfValue* val,
+ GConfValueType car_type,
+ GConfValueType cdr_type,
+ gpointer car_retloc,
+ gpointer cdr_retloc,
+ GConfError** err);
+
#endif
diff --git a/gconf/gconf.c b/gconf/gconf.c
index 268a1dec..a30fcd0a 100644
--- a/gconf/gconf.c
+++ b/gconf/gconf.c
@@ -449,11 +449,10 @@ gconf_get_with_locale(GConfEngine* conf, const gchar* key, const gchar* locale,
return NULL;
}
- if (locale == NULL)
- cv = ConfigServer_lookup(cs, priv->context, (gchar*)key, &ev);
- else
- cv = ConfigServer_lookup_with_locale(cs, priv->context,
- (gchar*)key, (gchar*)locale, &ev);
+ cv = ConfigServer_lookup_with_locale(cs, priv->context,
+ (gchar*)key, (gchar*)
+ (locale ? locale : gconf_current_locale()),
+ &ev);
if (gconf_server_broken(&ev))
@@ -1875,7 +1874,7 @@ gconf_get_list (GConfEngine* conf, const gchar* key,
g_return_val_if_fail(list_type != GCONF_VALUE_INVALID, NULL);
g_return_val_if_fail(list_type != GCONF_VALUE_LIST, NULL);
g_return_val_if_fail(list_type != GCONF_VALUE_PAIR, NULL);
- g_return_val_if_fail(err == NULL || *err == NULL, NULL);
+ g_return_val_if_fail(err == NULL || *err == NULL, NULL);
val = gconf_get_with_locale(conf, key, gconf_current_locale(), err);
@@ -1883,132 +1882,8 @@ gconf_get_list (GConfEngine* conf, const gchar* key,
return NULL;
else
{
- GSList* retval;
-
- if (val->type != GCONF_VALUE_LIST)
- {
- if (err)
- *err = gconf_error_new(GCONF_TYPE_MISMATCH,
- _("Expected list, got %s"),
- gconf_value_type_to_string(val->type));
- gconf_value_destroy(val);
- return NULL;
- }
-
- if (gconf_value_list_type(val) != list_type)
- {
- if (err)
- *err = gconf_error_new(GCONF_TYPE_MISMATCH,
- _("Expected list of %s, got list of %s"),
- gconf_value_type_to_string(list_type),
- gconf_value_type_to_string(val->type));
- gconf_value_destroy(val);
- return NULL;
- }
-
- g_assert(gconf_value_list_type(val) == list_type);
-
- retval = gconf_value_list(val);
-
- /* Cheating the API to avoid a list copy; set this to NULL to
- avoid destroying the list */
- val->d.list_data.list = NULL;
-
- gconf_value_destroy(val);
- val = NULL;
-
- {
- /* map (typeChange, retval) */
- GSList* tmp;
-
- tmp = retval;
-
- while (tmp != NULL)
- {
- GConfValue* elem = tmp->data;
-
- g_assert(elem != NULL);
- g_assert(elem->type == list_type);
-
- switch (list_type)
- {
- case GCONF_VALUE_INT:
- case GCONF_VALUE_BOOL:
- tmp->data = GINT_TO_POINTER(gconf_value_int(elem));
- break;
-
- case GCONF_VALUE_FLOAT:
- {
- gdouble* d = g_new(gdouble, 1);
- *d = gconf_value_float(elem);
- tmp->data = d;
- }
- break;
-
- case GCONF_VALUE_STRING:
- {
- /* Cheat again, and steal the string from the value */
- tmp->data = elem->d.string_data;
- elem->d.string_data = NULL;
- }
- break;
-
- case GCONF_VALUE_SCHEMA:
- {
- /* and also steal the schema... */
- tmp->data = elem->d.schema_data;
- elem->d.schema_data = NULL;
- }
- break;
-
- default:
- g_assert_not_reached();
- break;
- }
-
- /* Clean up the value */
- gconf_value_destroy(elem);
-
- tmp = g_slist_next(tmp);
- }
- } /* list conversion block */
-
- return retval;
- } /* else if val != NULL */
-}
-
-static void
-primitive_value(gpointer retloc, GConfValue* val)
-{
- switch (val->type)
- {
- case GCONF_VALUE_INT:
- *((gint*)retloc) = gconf_value_int(val);
- break;
-
- case GCONF_VALUE_FLOAT:
- *((gdouble*)retloc) = gconf_value_float(val);
- break;
-
- case GCONF_VALUE_STRING:
- {
- *((gchar**)retloc) = val->d.string_data;
- /* cheat and steal the string to avoid a copy */
- val->d.string_data = NULL;
- }
- break;
-
- case GCONF_VALUE_BOOL:
- *((gboolean*)retloc) = gconf_value_bool(val);
- break;
-
- case GCONF_VALUE_SCHEMA:
- *((GConfSchema**)retloc) = gconf_value_schema(val);
- break;
-
- default:
- g_assert_not_reached();
- break;
+ /* This type-checks the value */
+ return gconf_value_list_to_primitive_list_destructive(val, list_type, err);
}
}
@@ -2053,59 +1928,12 @@ gconf_get_pair (GConfEngine* conf, const gchar* key,
}
else
{
- GConfValue* car;
- GConfValue* cdr;
-
- if (val->type != GCONF_VALUE_PAIR)
- {
- if (err)
- *err = gconf_error_new(GCONF_TYPE_MISMATCH,
- _("Expected pair, got %s"),
- gconf_value_type_to_string(val->type));
- gconf_value_destroy(val);
- return FALSE;
- }
-
- car = gconf_value_car(val);
- cdr = gconf_value_cdr(val);
-
- if (car == NULL ||
- cdr == NULL)
- {
- if (err)
- *err = gconf_error_new(GCONF_TYPE_MISMATCH,
- _("Expected (%s,%s) pair, got a pair with one or both values missing"),
- gconf_value_type_to_string(car_type),
- gconf_value_type_to_string(cdr_type));
-
- gconf_value_destroy(val);
- return FALSE;
- }
-
- g_assert(car != NULL);
- g_assert(cdr != NULL);
-
- if (car->type != car_type ||
- cdr->type != cdr_type)
- {
- if (err)
- *err = gconf_error_new(GCONF_TYPE_MISMATCH,
- _("Expected pair of type (%s,%s) got type (%s,%s)"),
- gconf_value_type_to_string(car_type),
- gconf_value_type_to_string(cdr_type),
- gconf_value_type_to_string(car->type),
- gconf_value_type_to_string(cdr->type));
- gconf_value_destroy(val);
- return FALSE;
- }
-
- primitive_value(car_retloc, car);
- primitive_value(cdr_retloc, cdr);
-
- gconf_value_destroy(val);
-
- return TRUE;
- } /* else if val != NULL */
+ /* Destroys val */
+ return gconf_value_pair_to_primitive_pair_destructive(val,
+ car_type, cdr_type,
+ car_retloc, cdr_retloc,
+ err);
+ }
}
/*
@@ -2227,8 +2055,7 @@ gconf_set_list (GConfEngine* conf, const gchar* key,
GSList* list,
GConfError** err)
{
- GSList* value_list;
- GSList* tmp;
+ GConfValue* value_list;
g_return_val_if_fail(conf != NULL, FALSE);
g_return_val_if_fail(key != NULL, FALSE);
@@ -2236,99 +2063,12 @@ gconf_set_list (GConfEngine* conf, const gchar* key,
g_return_val_if_fail(list_type != GCONF_VALUE_LIST, FALSE);
g_return_val_if_fail(list_type != GCONF_VALUE_PAIR, FALSE);
g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
-
- value_list = NULL;
-
- tmp = list;
-
- while (tmp != NULL)
- {
- GConfValue* val;
-
- val = gconf_value_new(list_type);
-
- switch (list_type)
- {
- case GCONF_VALUE_INT:
- gconf_value_set_int(val, GPOINTER_TO_INT(tmp->data));
- break;
-
- case GCONF_VALUE_BOOL:
- gconf_value_set_bool(val, GPOINTER_TO_INT(tmp->data));
- break;
-
- case GCONF_VALUE_FLOAT:
- gconf_value_set_float(val, *((gdouble*)tmp->data));
- break;
-
- case GCONF_VALUE_STRING:
- gconf_value_set_string(val, tmp->data);
- break;
-
- case GCONF_VALUE_SCHEMA:
- gconf_value_set_schema(val, tmp->data);
- break;
-
- default:
- g_assert_not_reached();
- break;
- }
-
- value_list = g_slist_prepend(value_list, val);
- tmp = g_slist_next(tmp);
- }
-
- /* Get it in the right order. */
- value_list = g_slist_reverse(value_list);
-
- {
- GConfValue* value_with_list;
-
- value_with_list = gconf_value_new(GCONF_VALUE_LIST);
- gconf_value_set_list_type(value_with_list, list_type);
- gconf_value_set_list_nocopy(value_with_list, value_list);
-
- /* destroys the value_with_list */
- return error_checked_set(conf, key, value_with_list, err);
- }
-}
-
-static GConfValue*
-from_primitive(GConfValueType type, gconstpointer address)
-{
- GConfValue* val;
-
- val = gconf_value_new(type);
-
- switch (type)
- {
- case GCONF_VALUE_INT:
- gconf_value_set_int(val, *((const gint*)address));
- break;
-
- case GCONF_VALUE_BOOL:
- gconf_value_set_bool(val, *((const gboolean*)address));
- break;
-
- case GCONF_VALUE_STRING:
- gconf_value_set_string(val, *((const gchar**)address));
- break;
-
- case GCONF_VALUE_FLOAT:
- gconf_value_set_float(val, *((const gdouble*)address));
- break;
-
- case GCONF_VALUE_SCHEMA:
- gconf_value_set_schema(val, *((GConfSchema**)address));
- break;
-
- default:
- g_assert_not_reached();
- break;
- }
-
- return val;
+ value_list = gconf_value_list_from_primitive_list(list_type, list);
+
+ /* destroys the value_list */
+
+ return error_checked_set(conf, key, value_list, err);
}
gboolean
@@ -2339,8 +2079,6 @@ gconf_set_pair (GConfEngine* conf, const gchar* key,
GConfError** err)
{
GConfValue* pair;
- GConfValue* car;
- GConfValue* cdr;
g_return_val_if_fail(conf != NULL, FALSE);
g_return_val_if_fail(key != NULL, FALSE);
@@ -2354,13 +2092,10 @@ gconf_set_pair (GConfEngine* conf, const gchar* key,
g_return_val_if_fail(address_of_cdr != NULL, FALSE);
g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
- car = from_primitive(car_type, address_of_car);
- cdr = from_primitive(cdr_type, address_of_cdr);
-
- pair = gconf_value_new(GCONF_VALUE_PAIR);
- gconf_value_set_car_nocopy(pair, car);
- gconf_value_set_cdr_nocopy(pair, cdr);
+ pair = gconf_value_pair_from_primitive_pair(car_type, cdr_type,
+ address_of_car, address_of_cdr);
+
return error_checked_set(conf, key, pair, err);
}
diff --git a/gconf/gconf.h b/gconf/gconf.h
index aa761aa0..35dff14b 100644
--- a/gconf/gconf.h
+++ b/gconf/gconf.h
@@ -131,6 +131,7 @@ GSList* gconf_get_list (GConfEngine* conf, const gchar* key,
int gint*
string gchar**
float gdouble*
+ schema GConfSchema**
*/
gboolean gconf_get_pair (GConfEngine* conf, const gchar* key,
GConfValueType car_type, GConfValueType cdr_type,
diff --git a/wrappers/gtk/gconf-client.c b/wrappers/gtk/gconf-client.c
index 6e559fe4..131068b8 100644
--- a/wrappers/gtk/gconf-client.c
+++ b/wrappers/gtk/gconf-client.c
@@ -698,7 +698,7 @@ get(GConfClient* client, const gchar* key, GConfError** error)
/* Check our client-side cache */
if (gconf_client_lookup(client, key, &val))
- return val; /* stored in cache, not necessarily set though */
+ return gconf_value_copy(val); /* stored in cache, not necessarily set though */
g_assert(val == NULL); /* if it was in the cache we should have returned */
@@ -723,6 +723,7 @@ get(GConfClient* client, const gchar* key, GConfError** error)
if (gconf_key_is_below(d->name, key))
{
+ /* note that we cache a _copy_ */
gconf_client_cache(client, key,
val ? gconf_value_copy(val) : NULL);
break;
@@ -742,6 +743,8 @@ gconf_client_get_float (GConfClient* client, const gchar* key,
GConfError* error = NULL;
GConfValue* val;
+ g_return_val_if_fail(err == NULL || *err == NULL, 0.0);
+
val = get(client, key, &error);
if (val != NULL)
@@ -774,6 +777,8 @@ gconf_client_get_int (GConfClient* client, const gchar* key,
GConfError* error = NULL;
GConfValue* val;
+ g_return_val_if_fail(err == NULL || *err == NULL, 0);
+
val = get(client, key, &error);
if (val != NULL)
@@ -807,6 +812,8 @@ gconf_client_get_string(GConfClient* client, const gchar* key,
GConfError* error = NULL;
GConfValue* val;
+ g_return_val_if_fail(err == NULL || *err == NULL, NULL);
+
val = get(client, key, &error);
if (val != NULL)
@@ -846,6 +853,8 @@ gconf_client_get_bool (GConfClient* client, const gchar* key,
GConfError* error = NULL;
GConfValue* val;
+ g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
+
val = get(client, key, &error);
if (val != NULL)
@@ -878,6 +887,8 @@ gconf_client_get_schema (GConfClient* client,
GConfError* error = NULL;
GConfValue* val;
+ g_return_val_if_fail(err == NULL || *err == NULL, NULL);
+
val = get(client, key, &error);
if (val != NULL)
@@ -907,6 +918,89 @@ gconf_client_get_schema (GConfClient* client,
}
}
+GSList*
+gconf_client_get_list (GConfClient* client, const gchar* key,
+ GConfValueType list_type, GConfError** err)
+{
+ GConfError* error = NULL;
+ GConfValue* val;
+
+ g_return_val_if_fail(err == NULL || *err == NULL, NULL);
+
+ val = get(client, key, &error);
+
+ if (val != NULL)
+ {
+ GSList* retval;
+
+ g_assert(error == NULL);
+
+ /* This function checks the type and destroys "val" */
+ retval = gconf_value_list_to_primitive_list_destructive(val, list_type, &error);
+
+ if (error != NULL)
+ {
+ g_assert(retval == NULL);
+ handle_error(client, error, err);
+ return NULL;
+ }
+ else
+ return retval;
+ }
+ else
+ {
+ if (error != NULL)
+ handle_error(client, error, err);
+ return NULL;
+ }
+}
+
+gboolean
+gconf_client_get_pair (GConfClient* client, const gchar* key,
+ GConfValueType car_type, GConfValueType cdr_type,
+ gpointer car_retloc, gpointer cdr_retloc,
+ GConfError** err)
+{
+ GConfError* error = NULL;
+ GConfValue* val;
+
+ g_return_val_if_fail(err == NULL || *err == NULL, NULL);
+
+ val = get(client, key, &error);
+
+ if (val != NULL)
+ {
+ g_assert(error == NULL);
+
+ /* This function checks the type and destroys "val" */
+ if (gconf_value_pair_to_primitive_pair_destructive(val, car_type, cdr_type,
+ car_retloc, cdr_retloc,
+ &error))
+ {
+ g_assert(error == NULL);
+ return TRUE;
+ }
+ else
+ {
+ g_assert(error != NULL);
+ handle_error(client, error, err);
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (error != NULL)
+ {
+ handle_error(client, error, err);
+ return FALSE;
+ }
+ else
+ return TRUE;
+ }
+
+}
+
+
/*
* For the set functions, we just set normally, and wait for the
* notification to come back from the server before we update
@@ -1019,6 +1113,51 @@ gconf_client_set_schema (GConfClient* client, const gchar* key,
}
}
+gboolean
+gconf_client_set_list (GConfClient* client, const gchar* key,
+ GConfValueType list_type,
+ GSList* list,
+ GConfError** err)
+{
+ GConfError* error = NULL;
+
+ g_return_val_if_fail(client != NULL, FALSE);
+ g_return_val_if_fail(GCONF_IS_CLIENT(client), FALSE);
+ g_return_val_if_fail(key != NULL, FALSE);
+
+ if (gconf_set_list(client->engine, key, list_type, list, &error))
+ return TRUE;
+ else
+ {
+ handle_error(client, error, err);
+ return FALSE;
+ }
+}
+
+gboolean
+gconf_client_set_pair (GConfClient* client, const gchar* key,
+ GConfValueType car_type, GConfValueType cdr_type,
+ gconstpointer address_of_car,
+ gconstpointer address_of_cdr,
+ GConfError** err)
+{
+ GConfError* error = NULL;
+
+ g_return_val_if_fail(client != NULL, FALSE);
+ g_return_val_if_fail(GCONF_IS_CLIENT(client), FALSE);
+ g_return_val_if_fail(key != NULL, FALSE);
+
+ if (gconf_set_pair(client->engine, key, car_type, cdr_type,
+ address_of_car, address_of_car, &error))
+ return TRUE;
+ else
+ {
+ handle_error(client, error, err);
+ return FALSE;
+ }
+}
+
+
/*
* Functions to emit signals
*/
diff --git a/wrappers/gtk/gconf-client.h b/wrappers/gtk/gconf-client.h
index 68857ecc..311033a6 100644
--- a/wrappers/gtk/gconf-client.h
+++ b/wrappers/gtk/gconf-client.h
@@ -279,6 +279,14 @@ gboolean gconf_client_get_bool (GConfClient* client, const gchar* key,
GConfSchema* gconf_client_get_schema (GConfClient* client,
const gchar* key, GConfError** err);
+GSList* gconf_client_get_list (GConfClient* client, const gchar* key,
+ GConfValueType list_type, GConfError** err);
+
+gboolean gconf_client_get_pair (GConfClient* client, const gchar* key,
+ GConfValueType car_type, GConfValueType cdr_type,
+ gpointer car_retloc, gpointer cdr_retloc,
+ GConfError** err);
+
/* No convenience functions for lists or pairs, since there are too
many combinations of types possible
*/
@@ -300,6 +308,18 @@ gboolean gconf_client_set_bool (GConfClient* client, const gchar* key,
gboolean gconf_client_set_schema (GConfClient* client, const gchar* key,
GConfSchema* val, GConfError** err);
+/* List should be the same as the one gconf_client_get_list() would return */
+gboolean gconf_client_set_list (GConfClient* client, const gchar* key,
+ GConfValueType list_type,
+ GSList* list,
+ GConfError** err);
+
+gboolean gconf_client_set_pair (GConfClient* client, const gchar* key,
+ GConfValueType car_type, GConfValueType cdr_type,
+ gconstpointer address_of_car,
+ gconstpointer address_of_cdr,
+ GConfError** err);
+
/*
* Functions to emit signals
*/