Clientes GConf

El interfaz para clientes que ofrece GConf puede ser usado de dos formas distintas. Una es usando directamente el API, y otra usando una capa que se integra perfectamente con aplicaciones escritas para GTK/GNOME. Sea cual sea el modo que usemos, lo primero que tenemos que hacer en una aplicación que vaya a usar GConf, es inicializar la librería cliente de GConf, que se consigue con una llamada a la función gconf_init:

	gboolean gconf_init (int argc, char *argv[])
      

Esta función devuelve TRUE si tuvo éxito, o FALSE si hubo algun error. Los parámetros que recibe suelen ser típicamente los mismos que recibamos en la función main, pues gconf_init los necesita para procesar cualquier parámetro relacionado con CORBA/GConf que hubiera recibido nuestro programa.

Una vez que hemos inicializado la librería cliente GConf, ya podemos empezar a usar las funcionalidades de GConf. Pero para ello, lo primero que necesitamos es obtener una conexión con el sistema GConf, para lo que se usa el objeto GConfEngine. Este objeto representa una conexión con el motor de GConf (el demonio y los almacenes de datos manejados por éste), y lo necesitaremos para el resto de funciones de la librería.

Para obtener dicho objeto, podemos usar las siguientes dos funciones:

	GConfEngine *gconf_engine_get_default (void);
	GConfEngine *gconf_engine_get_default_with_address (const gchar *address);
      

La primera de estas funciones devuelve la conexión por defecto, mientras que la segunda nos permite activar una fuente de datos específica. En la mayoría de los casos, usaremos la primera función.

Ya con la conexión establecida, podemos comenzar a leer/escribir información a través de GConf. Para obtener valores de la base de datos, se usa la estructura GConfValue, que se obtienen mediante una llamada a la función gconf_engine_get:

	GConfEngine *engine;
	GConfValue *value;
	GError *error;

	engine = gconf_engine_get_default();
	value = gconf_engine_get(engine, "/aplicaciones/gnome/fondo", &error);
	switch (value->type) {
		case GCONF_VALUE_STRING :
			printf("%s\n", gconf_value_get_string(value));
			break;
		case GCONF_VALUE_INT:
			printf("%d\n", gconf_value_get_int(value));
			break;
		case GCONF_VALUE_FLOAT:
			printf("%g\n", gconf_value_get_float(value));
			break;
		case GCONF_VALUE_BOOL:
			printf("%s", gconf_value_get_bool(value) ? "true" : "false");
			break;
	}
      

La estructura GConfValue contiene toda la información necesaria sobre el valor obtenido de la base de datos, de forma que podemos, en nuestro programa, descubrir todas sus propiedades, como por ejemplo el tipo de datos, que es lo que se hace en este ejemplo de código.

Como vemos en el ejemplo, una variable de tipo GConfValue contiene los datos extraidos de la base de datos, sea cual sea su formato. Por ello, es importante que podamos preguntar cuáles son las características de esos datos, y así poder actuar en consecuencia. Se puede observar tambien en el ejemplo cómo tenemos varias funciones que nos permiten obtener el valor almacenado en la estructura en el formato asociado. Estas funciones son gconf_value_get_string, gconf_value_get_int, gconf_value_get_bool y gconf_value_get_float.

Pero la librería de GConf ofrece unas funciones de más alto nivel que nos permiten saltarnos el manejo de los GConfValue, y que son especialmente útiles cuando conocemos de antemano el tipo de datos asociado a los datos que queremos obtener a través de GConf. Estas funciones son las siguientes:

	gdouble gconf_engine_get_float (GConfEngine *conf, const gchar *key, GError **err);
	gint gconf_engine_get_int (GConfEngine *conf, const gchar *key, GError **err);
	gchar* gconf_engine_get_string (GConfEngine *conf, const gchar *key, GError **err);
	gboolean gconf_engine_get_bool (GConfEngine *conf, const gchar *key, GError **err);
      

Estas funciones son atajos directos para evitarnos el uso (a veces algo engorroso) de GConfValue y compañía. Estas funciones, internamente, hacen la conversión de GConfValue que veiamos antes en el ejemplo.

Análogamente a estas funciones, tenemos sus correspondientes funciones para escribir una entrada en la base de datos de configuración. Estas funciones son:

	gboolean gconf_engine_set_float (GConfEngine *conf, const gchar *key, gdouble val, GError **err);
	gboolean gconf_engine_set_int (GConfEngine *conf, const gchar *key, gint val, GError **err);
	gboolean gconf_engine_set_string (GConfEngine *conf, const gchar *key, const gchar *val, GError **err);
	gboolean gconf_engine_set_bool (GConfEngine *conf, const gchar *key, gboolean val, GError **err);
      

Todas estas funciones (tanto *_get_* como *_set_*) tienen un parámetro llamado key, que es una cadena que representa la entrada a la que nos estamos refiriendo (sería el camino completo del fichero).

Hay otro par de funciones que nos serán especialmente útiles cuando estemos leyendo datos de GConf. Son las siguientes:

	GSList *gconf_engine_all_entries (GConfEngine *engine, const gchar *dir, GError **error);
	GSList *gconf_engine_all_dirs (GConfEngine *engine, const gchar *dir, GError **error);
      

La primera de ellas, gconf_engine_all_dirs devuelve una lista de cadenas que representan el nombre de todas las secciones encontradas en el directorio (o sección) especificado en el parámetro dir.

	slist = gconf_engine_all_dirs(get_conf_engine(), path, NULL);
	if (slist) {
		GSList* node;

		for (node = slist; node != NULL; node = g_slist_next(node)) {
			printf("%s\n", (gchar *) node->data;
		}
		g_slist_free(slist);
	}
      

La segunda función, gconf_engine_all_entries, hace lo mismo, pero con dos "pequeñas" diferencias: devuelve una lista de claves y no de secciones, y cada uno de los elementos de la lista devuelta, en vez de ser una cadena de texto (de tipo gchar *), es de tipo GConfEntry.

	slist = gconf_engine_all_entries(get_conf_engine(), path, NULL);
	if (slist) {
		GSList* node;

		for (node = slist; node != NULL; node = g_slist_next(node)) {
			GConfEntry* entry = (GConfEntry *) node->data;
			printf("%s\n", gconf_entry_get_key(entry));
		}
		g_slist_free(slist);
	}