diff options
-rw-r--r-- | ChangeLog | 31 | ||||
-rw-r--r-- | gconf/gconf-changeset.c | 46 | ||||
-rw-r--r-- | gconf/gconf-changeset.h | 9 | ||||
-rw-r--r-- | gconf/gconf-client.c | 141 | ||||
-rw-r--r-- | gconf/gconf-client.h | 20 | ||||
-rw-r--r-- | gconf/gconf-internals.c | 354 | ||||
-rw-r--r-- | gconf/gconf-internals.h | 23 | ||||
-rw-r--r-- | gconf/gconf.c | 309 | ||||
-rw-r--r-- | gconf/gconf.h | 1 | ||||
-rw-r--r-- | wrappers/gtk/gconf-client.c | 141 | ||||
-rw-r--r-- | wrappers/gtk/gconf-client.h | 20 |
11 files changed, 806 insertions, 289 deletions
@@ -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 */ |