diff options
Diffstat (limited to 'gconf/gconf-dbus-utils.c')
-rw-r--r-- | gconf/gconf-dbus-utils.c | 1133 |
1 files changed, 1133 insertions, 0 deletions
diff --git a/gconf/gconf-dbus-utils.c b/gconf/gconf-dbus-utils.c new file mode 100644 index 00000000..6fd5bfa2 --- /dev/null +++ b/gconf/gconf-dbus-utils.c @@ -0,0 +1,1133 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ + +#include <config.h> +#include <string.h> +#include <dbus/dbus.h> + +#include "gconf/gconf.h" +#include "gconf-internals.h" +#include "gconf-dbus-utils.h" + +#define d(x) + +/* Entry: + * + * struct { + * string key; + * struct value; + * + * boolean schema_name_set; + * string schema_name; + * + * boolean is_default; + * boolean is_writable; + * }; + * + */ + +/* Pair: + * + * struct { + * int32 car_type; + * <fundamental> car_value; + + * int32 cdr_type; + * <fundamental> cdr_value; + * }; + * + */ + +/* List: + * + * struct { + * int32 list_type; + * array<fundamental> values; + * }; + * + */ + +/* Value: + * + * struct { + * int32 type; + * <int, string, float, bool, list, pair, schema> value; + * }; + * + */ + +/* Schema: + * + * struct { + * int32 type; + * int32 list_type; + * int32 car_type; + * int32 cdr_type; + + * boolean locale_set; + * string locale; + + * boolean short_desc_set; + * string short_desc; + + * boolean long_desc_set; + * string long_desc; + + * boolean owner_set; + * string owner; + + * boolean gettext_domain_set; + * string gettext_domain; + + * string default_value; + * }; + * + */ + +static void utils_append_value_helper_fundamental (DBusMessageIter *iter, + const GConfValue *value); +static void utils_append_value_helper_pair (DBusMessageIter *main_iter, + const GConfValue *value); +static void utils_append_value_helper_list (DBusMessageIter *main_iter, + const GConfValue *value); +static void utils_append_schema (DBusMessageIter *main_iter, + const GConfSchema *schema); +static void utils_append_value (DBusMessageIter *main_iter, + const GConfValue *value); + +static GConfValue * utils_get_value_helper_fundamental (DBusMessageIter *iter, + GConfValueType value_type); +static GConfValue * utils_get_value_helper_pair (DBusMessageIter *iter); +static GConfValue * utils_get_value_helper_list (DBusMessageIter *iter); +static GConfValue * utils_get_value (DBusMessageIter *main_iter); +static GConfSchema *utils_get_schema (DBusMessageIter *main_iter); +static GConfValue * utils_get_schema_value (DBusMessageIter *iter); + + +/* + * Utilities + */ + +/* A boolean followed by a string. */ +static void +utils_append_optional_string (DBusMessageIter *iter, + const gchar *str) +{ + gboolean is_set; + + if (str) + is_set = TRUE; + else + { + is_set = FALSE; + str = ""; + } + + dbus_message_iter_append_basic (iter, DBUS_TYPE_BOOLEAN, &is_set); + dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &str); +} + +/* A boolean followed by a string. */ +static const gchar * +utils_get_optional_string (DBusMessageIter *iter) +{ + gboolean is_set; + const gchar *str; + + dbus_message_iter_get_basic (iter, &is_set); + dbus_message_iter_next (iter); + dbus_message_iter_get_basic (iter, &str); + + if (is_set) + return str; + else + return NULL; +} + + +/* + * Setters + */ + + +/* Helper for utils_append_value, writes a int/string/float/bool/schema. + */ +static void +utils_append_value_helper_fundamental (DBusMessageIter *iter, + const GConfValue *value) +{ + gint32 i; + gboolean b; + const gchar *s; + gdouble d; + + d(g_print ("Append value (fundamental)\n")); + + switch (value->type) + { + case GCONF_VALUE_INT: + i = gconf_value_get_int (value); + dbus_message_iter_append_basic (iter, DBUS_TYPE_INT32, &i); + break; + + case GCONF_VALUE_STRING: + s = gconf_value_get_string (value); + dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &s); + break; + + case GCONF_VALUE_FLOAT: + d = gconf_value_get_float (value); + dbus_message_iter_append_basic (iter, DBUS_TYPE_DOUBLE, &d); + break; + + case GCONF_VALUE_BOOL: + b = gconf_value_get_bool (value); + dbus_message_iter_append_basic (iter, DBUS_TYPE_BOOLEAN, &b); + break; + + case GCONF_VALUE_SCHEMA: + utils_append_schema (iter, gconf_value_get_schema (value)); + break; + + default: + g_assert_not_reached (); + } +} + +/* Helper for utils_append_value, writes a pair. The pair is a struct with the + * two values and two fundamental values (type, value, type value). + */ +static void +utils_append_value_helper_pair (DBusMessageIter *main_iter, + const GConfValue *value) +{ + DBusMessageIter struct_iter; + GConfValue *car, *cdr; + gint32 type; + + d(g_print ("Append value (pair)\n")); + + g_assert (value->type == GCONF_VALUE_PAIR); + + dbus_message_iter_open_container (main_iter, + DBUS_TYPE_STRUCT, + NULL, /* for struct */ + &struct_iter); + + car = gconf_value_get_car (value); + cdr = gconf_value_get_cdr (value); + + /* The pair types. */ + if (car) + type = car->type; + else + type = GCONF_VALUE_INVALID; + dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_INT32, &type); + + if (cdr) + type = cdr->type; + else + type = GCONF_VALUE_INVALID; + dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_INT32, &type); + + /* The values. */ + if (car) + utils_append_value_helper_fundamental (&struct_iter, car); + + if (cdr) + utils_append_value_helper_fundamental (&struct_iter, cdr); + + dbus_message_iter_close_container (main_iter, &struct_iter); +} + +/* Helper for utils_append_value, writes a list. The "list" is a struct with the + * list type and an array with the values directly in it. + */ +static void +utils_append_value_helper_list (DBusMessageIter *main_iter, + const GConfValue *value) +{ + DBusMessageIter struct_iter; + DBusMessageIter array_iter; + GConfValueType list_type; + const gchar *array_type; + GSList *list; + + d(g_print ("Append value (list)\n")); + + g_assert (value->type == GCONF_VALUE_LIST); + + dbus_message_iter_open_container (main_iter, + DBUS_TYPE_STRUCT, + NULL, /* for struct */ + &struct_iter); + + /* Write the list type. */ + list_type = gconf_value_get_list_type (value); + dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_INT32, &list_type); + + /* And the value. */ + switch (list_type) + { + case GCONF_VALUE_INT: + array_type = DBUS_TYPE_INT32_AS_STRING; + break; + + case GCONF_VALUE_STRING: + array_type = DBUS_TYPE_STRING_AS_STRING; + break; + + case GCONF_VALUE_FLOAT: + array_type = DBUS_TYPE_DOUBLE_AS_STRING; + break; + + case GCONF_VALUE_BOOL: + array_type = DBUS_TYPE_BOOLEAN_AS_STRING; + break; + + case GCONF_VALUE_SCHEMA: + array_type = DBUS_TYPE_STRUCT_AS_STRING; + break; + + default: + array_type = NULL; + g_assert_not_reached (); + } + + dbus_message_iter_open_container (&struct_iter, + DBUS_TYPE_ARRAY, + array_type, + &array_iter); + + list = gconf_value_get_list (value); + + switch (list_type) + { + case GCONF_VALUE_STRING: + while (list) + { + const gchar *s; + + s = gconf_value_get_string (list->data); + dbus_message_iter_append_basic (&array_iter, + DBUS_TYPE_STRING, + &s); + + list = list->next; + } + break; + + case GCONF_VALUE_INT: + while (list) + { + gint32 i; + + i = gconf_value_get_int (list->data); + dbus_message_iter_append_basic (&array_iter, + DBUS_TYPE_INT32, + &i); + + list = list->next; + } + break; + + case GCONF_VALUE_FLOAT: + while (list) + { + gdouble d; + + d = gconf_value_get_float (list->data); + dbus_message_iter_append_basic (&array_iter, + DBUS_TYPE_DOUBLE, + &d); + + list = list->next; + } + break; + + case GCONF_VALUE_BOOL: + while (list) + { + gboolean b; + + b = gconf_value_get_bool (list->data); + dbus_message_iter_append_basic (&array_iter, + DBUS_TYPE_BOOLEAN, + &b); + + list = list->next; + } + break; + + case GCONF_VALUE_SCHEMA: + while (list) + { + GConfSchema *schema; + + schema = gconf_value_get_schema (list->data); + utils_append_schema (&array_iter, schema); + + list = list->next; + } + break; + + default: + g_assert_not_reached (); + } + + dbus_message_iter_close_container (&struct_iter, &array_iter); + dbus_message_iter_close_container (main_iter, &struct_iter); +} + +/* Writes a schema, which is a struct. */ +static void +utils_append_schema (DBusMessageIter *main_iter, + const GConfSchema *schema) +{ + DBusMessageIter struct_iter; + gint32 i; + const gchar *s; + GConfValue *default_value; + + dbus_message_iter_open_container (main_iter, + DBUS_TYPE_STRUCT, + NULL, /* for structs */ + &struct_iter); + + i = gconf_schema_get_type (schema); + dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_INT32, &i); + + i = gconf_schema_get_list_type (schema); + dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_INT32, &i); + + i = gconf_schema_get_car_type (schema); + dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_INT32, &i); + + i = gconf_schema_get_cdr_type (schema); + dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_INT32, &i); + + s = gconf_schema_get_locale (schema); + utils_append_optional_string (&struct_iter, s); + + s = gconf_schema_get_short_desc (schema); + utils_append_optional_string (&struct_iter, s); + + s = gconf_schema_get_long_desc (schema); + utils_append_optional_string (&struct_iter, s); + + s = gconf_schema_get_owner (schema); + utils_append_optional_string (&struct_iter, s); + + default_value = gconf_schema_get_default_value (schema); + + /* We don't need to do this, but it's much simpler */ + if (default_value) + { + gchar *encoded; + + encoded = gconf_value_encode (default_value); + g_assert (encoded != NULL); + + dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_STRING, &encoded); + g_free (encoded); + } + else + { + s = ""; + dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_STRING, &s); + } + + if (!dbus_message_iter_close_container (main_iter, &struct_iter)) + g_error ("Out of memory"); +} + +static void +utils_append_value (DBusMessageIter *main_iter, + const GConfValue *value) +{ + DBusMessageIter struct_iter; + gint32 type; + + /* A value is stored as a struct with the type and the actual value. */ + dbus_message_iter_open_container (main_iter, + DBUS_TYPE_STRUCT, + NULL, /* for structs */ + &struct_iter); + + if (!value) + type = GCONF_VALUE_INVALID; + else + type = value->type; + + dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_INT32, &type); + + switch (type) + { + case GCONF_VALUE_INT: + case GCONF_VALUE_STRING: + case GCONF_VALUE_FLOAT: + case GCONF_VALUE_BOOL: + case GCONF_VALUE_SCHEMA: + utils_append_value_helper_fundamental (&struct_iter, value); + break; + + case GCONF_VALUE_LIST: + utils_append_value_helper_list (&struct_iter, value); + break; + + case GCONF_VALUE_PAIR: + utils_append_value_helper_pair (&struct_iter, value); + break; + + case GCONF_VALUE_INVALID: + break; + + default: + g_assert_not_reached (); + } + + dbus_message_iter_close_container (main_iter, &struct_iter); +} + +/* Writes an entry, which is a struct. */ +static void +utils_append_entry_values (DBusMessageIter *main_iter, + const gchar *key, + const GConfValue *value, + gboolean is_default, + gboolean is_writable, + const gchar *schema_name) +{ + DBusMessageIter struct_iter; + + d(g_print ("Appending entry %s\n", key)); + + dbus_message_iter_open_container (main_iter, + DBUS_TYPE_STRUCT, + NULL, /* for structs */ + &struct_iter); + + dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_STRING, &key); + + utils_append_value (&struct_iter, value); + + utils_append_optional_string (&struct_iter, schema_name); + + dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_BOOLEAN, &is_default); + + dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_BOOLEAN, &is_writable); + + dbus_message_iter_close_container (main_iter, &struct_iter); +} + +/* Writes an entry, which is a struct. */ +static void +utils_append_entry_values_stringified (DBusMessageIter *main_iter, + const gchar *key, + const GConfValue *value, + gboolean is_default, + gboolean is_writable, + const gchar *schema_name) +{ + DBusMessageIter struct_iter; + gchar *value_str; + + d(g_print ("Appending entry %s\n", key)); + + dbus_message_iter_open_container (main_iter, + DBUS_TYPE_STRUCT, + NULL, /* for structs */ + &struct_iter); + + dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_STRING, &key); + + value_str = NULL; + if (value) + value_str = gconf_value_encode ((GConfValue *) value); + + if (!value_str) + value_str = g_strdup (""); + + dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_STRING, &value_str); + g_free (value_str); + + utils_append_optional_string (&struct_iter, schema_name); + + dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_BOOLEAN, &is_default); + + dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_BOOLEAN, &is_writable); + + if (!dbus_message_iter_close_container (main_iter, &struct_iter)) + g_error ("Out of memory"); +} + +gboolean +gconf_dbus_utils_get_entry_values (DBusMessageIter *main_iter, + gchar **key_p, + GConfValue **value_p, + gboolean *is_default_p, + gboolean *is_writable_p, + gchar **schema_name_p) +{ + DBusMessageIter struct_iter; + gchar *key; + GConfValue *value; + gboolean is_default; + gboolean is_writable; + gchar *schema_name; + + g_return_val_if_fail (dbus_message_iter_get_arg_type (main_iter) == DBUS_TYPE_STRUCT, + FALSE); + + dbus_message_iter_recurse (main_iter, &struct_iter); + dbus_message_iter_get_basic (&struct_iter, &key); + + d(g_print ("Getting entry %s\n", key)); + + dbus_message_iter_next (&struct_iter); + value = utils_get_value (&struct_iter); + + dbus_message_iter_next (&struct_iter); + schema_name = (gchar *) utils_get_optional_string (&struct_iter); + + dbus_message_iter_next (&struct_iter); + dbus_message_iter_get_basic (&struct_iter, &is_default); + + dbus_message_iter_next (&struct_iter); + dbus_message_iter_get_basic (&struct_iter, &is_writable); + + if (key_p) + *key_p = key; + + if (value_p) + *value_p = value; + else if (value) + gconf_value_free (value); + + if (schema_name_p) + *schema_name_p = schema_name; + + if (is_default_p) + *is_default_p = is_default; + + if (is_writable_p) + *is_writable_p = is_writable; + + return TRUE; +} + +static gboolean +utils_get_entry_values_stringified (DBusMessageIter *main_iter, + gchar **key_p, + GConfValue **value_p, + gboolean *is_default_p, + gboolean *is_writable_p, + gchar **schema_name_p) +{ + DBusMessageIter struct_iter; + gchar *key; + gchar *value_str; + GConfValue *value; + gboolean is_default; + gboolean is_writable; + gchar *schema_name; + + dbus_message_iter_recurse (main_iter, &struct_iter); + dbus_message_iter_get_basic (&struct_iter, &key); + + d(g_print ("Getting entry %s\n", key)); + + dbus_message_iter_next (&struct_iter); + dbus_message_iter_get_basic (&struct_iter, &value_str); + if (value_str[0] != '\0') + value = gconf_value_decode (value_str); + else + value = NULL; + + dbus_message_iter_next (&struct_iter); + schema_name = (gchar *) utils_get_optional_string (&struct_iter); + + dbus_message_iter_next (&struct_iter); + dbus_message_iter_get_basic (&struct_iter, &is_default); + + dbus_message_iter_next (&struct_iter); + dbus_message_iter_get_basic (&struct_iter, &is_writable); + + if (key_p) + *key_p = key; + + if (value_p) + *value_p = value; + else + gconf_value_free (value); + + if (schema_name_p) + *schema_name_p = schema_name; + + if (is_default_p) + *is_default_p = is_default; + + if (is_writable_p) + *is_writable_p = is_writable; + + return TRUE; +} + + +/* + * Getters + */ + +/* Helper for utils_get_value, reads int/string/float/bool/schema. */ +static GConfValue * +utils_get_value_helper_fundamental (DBusMessageIter *iter, + GConfValueType value_type) +{ + GConfValue *value; + GConfSchema *schema; + gint32 i; + const gchar *s; + gdouble d; + gboolean b; + + d(g_print ("Get value (fundamental)\n")); + + if (value_type == GCONF_VALUE_INVALID) + return NULL; + + value = gconf_value_new (value_type); + + switch (value_type) + { + case GCONF_VALUE_INT: + dbus_message_iter_get_basic (iter, &i); + gconf_value_set_int (value, i); + break; + + case GCONF_VALUE_STRING: + dbus_message_iter_get_basic (iter, &s); + gconf_value_set_string (value, s); + break; + + case GCONF_VALUE_FLOAT: + dbus_message_iter_get_basic (iter, &d); + gconf_value_set_float (value, d); + break; + + case GCONF_VALUE_BOOL: + dbus_message_iter_get_basic (iter, &b); + gconf_value_set_bool (value, b); + break; + + case GCONF_VALUE_SCHEMA: + schema = utils_get_schema (iter); + gconf_value_set_schema_nocopy (value, schema); + break; + + default: + g_assert_not_reached (); + } + + return value; +} + +/* Helper for utils_get_value, reads a pair. The pair is a struct with the two + * values and two fundamental values (type, value, type, value). + */ +static GConfValue * +utils_get_value_helper_pair (DBusMessageIter *iter) +{ + GConfValue *value; + DBusMessageIter struct_iter; + gint32 car_type, cdr_type; + GConfValue *car_value = NULL, *cdr_value = NULL; + + d(g_print ("Get value (pair)\n")); + + value = gconf_value_new (GCONF_VALUE_PAIR); + + /* Get the pair types. */ + dbus_message_iter_recurse (iter, &struct_iter); + dbus_message_iter_get_basic (&struct_iter, &car_type); + dbus_message_iter_next (&struct_iter); + dbus_message_iter_get_basic (&struct_iter, &cdr_type); + + /* Get the values. */ + dbus_message_iter_next (&struct_iter); + if (car_type == GCONF_VALUE_SCHEMA) + car_value = utils_get_schema_value (&struct_iter); + else if (car_type != GCONF_VALUE_INVALID) + car_value = utils_get_value_helper_fundamental (&struct_iter, car_type); + + dbus_message_iter_next (&struct_iter); + if (cdr_type == GCONF_VALUE_SCHEMA) + cdr_value = utils_get_schema_value (&struct_iter); + else if (cdr_type != GCONF_VALUE_INVALID) + cdr_value = utils_get_value_helper_fundamental (&struct_iter, cdr_type); + + if (car_value) + gconf_value_set_car_nocopy (value, car_value); + + if (cdr_value) + gconf_value_set_cdr_nocopy (value, cdr_value); + + return value; +} + +/* Helper for utils_get_value, reads a list. The "list" is a struct with the + * list type and an array with the values directly in it. + */ +static GConfValue * +utils_get_value_helper_list (DBusMessageIter *iter) +{ + DBusMessageIter struct_iter; + DBusMessageIter array_iter; + GConfValue *value; + gint32 list_type; + GSList *list; + GConfValue *child_value; + + d(g_print ("Get value (list)\n")); + + value = gconf_value_new (GCONF_VALUE_LIST); + + dbus_message_iter_recurse (iter, &struct_iter); + + /* Get the list type. */ + dbus_message_iter_get_basic (&struct_iter, &list_type); + gconf_value_set_list_type (value, list_type); + + /* Get the array. */ + dbus_message_iter_next (&struct_iter); + dbus_message_iter_recurse (&struct_iter, &array_iter); + + /* And the values from the array. */ + list = NULL; + switch (list_type) + { + case GCONF_VALUE_STRING: + while (dbus_message_iter_get_arg_type (&array_iter) == DBUS_TYPE_STRING) + { + const gchar *str; + + dbus_message_iter_get_basic (&array_iter, &str); + + child_value = gconf_value_new (GCONF_VALUE_STRING); + gconf_value_set_string (child_value, str); + list = g_slist_prepend (list, child_value); + + dbus_message_iter_next (&array_iter); + } + break; + + case GCONF_VALUE_INT: + while (dbus_message_iter_get_arg_type (&array_iter) == DBUS_TYPE_INT32) + { + gint32 i; + + dbus_message_iter_get_basic (&array_iter, &i); + + child_value = gconf_value_new (GCONF_VALUE_INT); + gconf_value_set_int (child_value, i); + list = g_slist_prepend (list, child_value); + + dbus_message_iter_next (&array_iter); + } + break; + + case GCONF_VALUE_FLOAT: + while (dbus_message_iter_get_arg_type (&array_iter) == DBUS_TYPE_DOUBLE) + { + gdouble d; + + dbus_message_iter_get_basic (&array_iter, &d); + + child_value = gconf_value_new (GCONF_VALUE_FLOAT); + gconf_value_set_float (child_value, d); + list = g_slist_prepend (list, child_value); + + dbus_message_iter_next (&array_iter); + } + break; + + case GCONF_VALUE_BOOL: + while (dbus_message_iter_get_arg_type (&array_iter) == DBUS_TYPE_BOOLEAN) + { + gboolean b; + + dbus_message_iter_get_basic (&array_iter, &b); + + child_value = gconf_value_new (GCONF_VALUE_BOOL); + gconf_value_set_bool (child_value, b); + list = g_slist_prepend (list, child_value); + + dbus_message_iter_next (&array_iter); + } + break; + + case GCONF_VALUE_SCHEMA: + while (dbus_message_iter_get_arg_type (&array_iter) == DBUS_TYPE_STRUCT) + { + child_value = utils_get_schema_value (&array_iter); + list = g_slist_prepend (list, child_value); + + dbus_message_iter_next (&array_iter); + } + break; + + default: + g_assert_not_reached (); + } + + list = g_slist_reverse (list); + gconf_value_set_list_nocopy (value, list); + + return value; +} + +static GConfValue * +utils_get_value (DBusMessageIter *main_iter) +{ + DBusMessageIter struct_iter; + gint32 type; + GConfValue *value; + + g_assert (dbus_message_iter_get_arg_type (main_iter) == DBUS_TYPE_STRUCT); + + /* A value is stored as a struct with the type and a variant with the actual + * value. + */ + + dbus_message_iter_recurse (main_iter, &struct_iter); + dbus_message_iter_get_basic (&struct_iter, &type); + + dbus_message_iter_next (&struct_iter); + + switch (type) + { + case GCONF_VALUE_INT: + case GCONF_VALUE_STRING: + case GCONF_VALUE_BOOL: + case GCONF_VALUE_FLOAT: + value = utils_get_value_helper_fundamental (&struct_iter, type); + break; + + case GCONF_VALUE_PAIR: + value = utils_get_value_helper_pair (&struct_iter); + break; + + case GCONF_VALUE_LIST: + value = utils_get_value_helper_list (&struct_iter); + break; + + case GCONF_VALUE_SCHEMA: + value = utils_get_schema_value (&struct_iter); + break; + + case GCONF_VALUE_INVALID: + value = NULL; + break; + + default: + value = NULL; + g_assert_not_reached (); + } + + return value; +} + +static GConfSchema * +utils_get_schema (DBusMessageIter *main_iter) +{ + DBusMessageIter struct_iter; + gint32 type, list_type, car_type, cdr_type; + const gchar *locale, *short_desc, *long_desc, *owner; + const gchar *encoded; + GConfSchema *schema; + GConfValue *default_value; + + g_assert (dbus_message_iter_get_arg_type (main_iter) == DBUS_TYPE_STRUCT); + + dbus_message_iter_recurse (main_iter, &struct_iter); + dbus_message_iter_get_basic (&struct_iter, &type); + + dbus_message_iter_next (&struct_iter); + dbus_message_iter_get_basic (&struct_iter, &list_type); + + dbus_message_iter_next (&struct_iter); + dbus_message_iter_get_basic (&struct_iter, &car_type); + + dbus_message_iter_next (&struct_iter); + dbus_message_iter_get_basic (&struct_iter, &cdr_type); + + dbus_message_iter_next (&struct_iter); + locale = utils_get_optional_string (&struct_iter); + + dbus_message_iter_next (&struct_iter); + short_desc = utils_get_optional_string (&struct_iter); + + dbus_message_iter_next (&struct_iter); + long_desc = utils_get_optional_string (&struct_iter); + + dbus_message_iter_next (&struct_iter); + owner = utils_get_optional_string (&struct_iter); + + dbus_message_iter_next (&struct_iter); + dbus_message_iter_get_basic (&struct_iter, &encoded); + + schema = gconf_schema_new (); + + gconf_schema_set_type (schema, type); + gconf_schema_set_list_type (schema, list_type); + gconf_schema_set_car_type (schema, car_type); + gconf_schema_set_cdr_type (schema, cdr_type); + + if (locale) + gconf_schema_set_locale (schema, locale); + + if (short_desc) + gconf_schema_set_short_desc (schema, short_desc); + + if (long_desc) + gconf_schema_set_long_desc (schema, long_desc); + + if (owner) + gconf_schema_set_owner (schema, owner); + + if (*encoded != '\0') + { + default_value = gconf_value_decode (encoded); + if (default_value) + gconf_schema_set_default_value_nocopy (schema, default_value); + } + + return schema; +} + +static GConfValue * +utils_get_schema_value (DBusMessageIter *iter) +{ + GConfSchema *schema; + GConfValue *value; + + schema = utils_get_schema (iter); + + value = gconf_value_new (GCONF_VALUE_SCHEMA); + gconf_value_set_schema_nocopy (value, schema); + + return value; +} + + +/* + * Public API + */ + +void +gconf_dbus_utils_append_value (DBusMessageIter *iter, + const GConfValue *value) +{ + utils_append_value (iter, value); +} + +GConfValue * +gconf_dbus_utils_get_value (DBusMessageIter *iter) +{ + return utils_get_value (iter); +} + +void +gconf_dbus_utils_append_entry_values (DBusMessageIter *iter, + const gchar *key, + const GConfValue *value, + gboolean is_default, + gboolean is_writable, + const gchar *schema_name) +{ + utils_append_entry_values (iter, + key, + value, + is_default, + is_writable, + schema_name); +} + +/* Append the list of entries as an array. */ +void +gconf_dbus_utils_append_entries (DBusMessageIter *iter, + GSList *entries) +{ + DBusMessageIter array_iter; + GSList *l; + + dbus_message_iter_open_container (iter, + DBUS_TYPE_ARRAY, + DBUS_STRUCT_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_BOOLEAN_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_BOOLEAN_AS_STRING + DBUS_TYPE_BOOLEAN_AS_STRING + DBUS_STRUCT_END_CHAR_AS_STRING, + &array_iter); + + for (l = entries; l; l = l->next) + { + GConfEntry *entry = l->data; + + utils_append_entry_values_stringified (&array_iter, + entry->key, + gconf_entry_get_value (entry), + gconf_entry_get_is_default (entry), + gconf_entry_get_is_writable (entry), + gconf_entry_get_schema_name (entry)); + } + + dbus_message_iter_close_container (iter, &array_iter); +} + +/* Get a list of entries from an array. */ +GSList * +gconf_dbus_utils_get_entries (DBusMessageIter *iter, const gchar *dir) +{ + GSList *entries; + DBusMessageIter array_iter; + + entries = NULL; + + dbus_message_iter_recurse (iter, &array_iter); + + /* Loop through while there are structs (entries). */ + while (dbus_message_iter_get_arg_type (&array_iter) == DBUS_TYPE_STRUCT) + { + gchar *key; + GConfValue *value; + gboolean is_default; + gboolean is_writable; + gchar *schema_name; + GConfEntry *entry; + + if (!utils_get_entry_values_stringified (&array_iter, + &key, + &value, + &is_default, + &is_writable, + &schema_name)) + break; + + entry = gconf_entry_new_nocopy (gconf_concat_dir_and_key (dir, key), value); + + gconf_entry_set_is_default (entry, is_default); + gconf_entry_set_is_writable (entry, is_writable); + + if (schema_name) + gconf_entry_set_schema_name (entry, schema_name); + + entries = g_slist_prepend (entries, entry); + + dbus_message_iter_next (&array_iter); + } + + return entries; +} + |