Ikke's Blog

Post details: GConf introduction

Jul 16
GConf introduction

I played a little with GConf today. Here's some little introduction to it.

We'll be doing 3 very simple things today:

  1. Read out GConf key values

  2. Set key values

  3. Read out values, and register to value changes

Reading out a string from the GConf tree

Reading out a value (in our case a string) is very simple: first of all you need to know which string you want to read. In this sample we'll try to get the value of the default browser. Then you create a GConfClient, a proxy to the GConf system, you query gconfd using the proxy, get the value and do something with it.

Here's the code:

/* GConf test reader
 * Compile using
 *      gcc `pkg-config --libs --cflags gconf-2.0` -o reader reader.c
 */

#include <glib.h>
#include <gconf/gconf-client.h>

/* Path to the key we'll be working with */
#define GCKEY "/desktop/gnome/applications/browser/exec"

gint main(gint argc, gchar *argv[]) {
        /* Our proxy */
        GConfClient *gclient = NULL;
        /* String to store the GCKEY's value in */
        gchar *val = NULL;

        /* Initialize the GConf subsystem */
        gconf_init(argc, argv, NULL);

        g_print("Working with key \"%s\"\n", "" GCKEY);
        
        /* Get the default GConf proxy */
        gclient = gconf_client_get_default();
        g_assert(gclient != NULL);

        /* Get the value of GCKEY */
        val = gconf_client_get_string(gclient, "" GCKEY, NULL);
        if(val == NULL) {
                /* Key was not set before */
                val = g_strdup("<unset>");
        }
        g_assert(val != NULL);

        g_print("Value: \"%s\"\n", val);

        g_free(val);

        return 0;
}

As you can see this is very straight-forward.
Now compile and run the code:

ikke@marslander ~/Projects/gconf $ gcc `pkg-config --libs --cflags gconf-2.0` -o reader reader.c
ikke@marslander ~/Projects/gconf $ ./reader
Working with key "/desktop/gnome/applications/browser/exec"
Value: "mozilla"

Setting a key value

To set a key, once more we just need a GConfClient proxy, and call a function to set the new key value:

/* GConf test writer
 * Compile using
 *      gcc `pkg-config --libs --cflags gconf-2.0` -o setkey setkey.c
 */

#include <glib.h>
#include <gconf/gconf-client.h>

/* Path to the key we'll be working with */
#define GCKEY "/extra/test/key"

gint main(gint argc, gchar *argv[]) {
        /* Our proxy */
        GConfClient *gclient = NULL;
        /* New value */
        gchar *val = NULL;

        /* Initialize the GConf subsystem */
        gconf_init(argc, argv, NULL);

        if(argc > 1) {
                val = g_strdup(argv[1]);
        }
        else {
                val = g_strdup("testval");
        }

        g_print("Working with key \"%s\"\n", "" GCKEY);
        
        /* Get the default GConf proxy */
        gclient = gconf_client_get_default();
        g_assert(gclient != NULL);

        g_assert(val != NULL);
        gconf_client_set_string(gclient, "" GCKEY, val, NULL);

        g_print("Value \"%s\" set\n", val);

        g_free(val);

        return 0;
}

Again, compile the code and play around with it:

ikke@marslander ~/Projects/gconf $ gcc `pkg-config --libs --cflags gconf-2.0` -o setkey setkey.c
ikke@marslander ~/Projects/gconf $ ./setkey
Working with key "/extra/test/key"
Value "testval" set
ikke@marslander ~/Projects/gconf $ ./setkey test2
Working with key "/extra/test/key"
Value "test2" set

Now you might want to alter reader.c and compile it again so it reads out this new key instead of the one we used before.

Using change notifications

At last we'll be using one of the more advanced features of GConf, change notifications. This means we can register a callback to a key change, so when the key's value is changed (in-process or by another process) we'll be notified of this.
One again this is very easy: get a GConfClient proxy, figure out to which key you want to subscribe, find out the container directory, tell gconfd you want to register to that "directory", add a key change event handler, and you're done. This might sound confusing, read the code sample to see how easy it is.

/* GConf test listener
 * Compile using
 *      gcc `pkg-config --libs --cflags gconf-2.0` -o listener listener.c
 */

#include <glib.h>
#include <gconf/gconf-client.h>

/* The GConf PATH we'll want to monitor */
#define GCPATH "/extra/test"
/* Path to the key we'll be working with */
#define GCKEY "/extra/test/key"

/* This is the callback function for GCKEY changes */
void key_changed_cb(GConfClient* client, guint cnxn_id, GConfEntry *entry, gpointer user_data) {
        /* Store the new key value */
        gchar *val = NULL;
        /* A local GConfValue */
        GConfValue *value = NULL;

        /* Get the value from the provided entry */
        value = gconf_entry_get_value(entry);
        
        /* This should not happen, but one never knows */
        if(value == NULL) {
                val = g_strdup("<unset>");
        }
        else {
                /* Check value type, we want a string */
                if(value->type == GCONF_VALUE_STRING) {
                        /* Get the key value
                         * We use g_strdup because we'll g_free(val) later */
                        val = g_strdup(gconf_value_get_string(value));
                }
                else {
                        val = g_strdup("<wrong type>");
                }
        }
        g_assert(val != NULL);

        g_print("Value changed: \"%s\"\n", val);

        g_free(val);
}

gint main(gint argc, gchar *argv[]) {
        /* Our proxy */
        GConfClient *gclient = NULL;
        /* String to store the GCKEY's value in */
        gchar *val = NULL;
        /* A simple mainloop */
        GMainLoop *loop = NULL;

        /* Initialize the GConf subsystem */
        gconf_init(argc, argv, NULL);

        g_print("Working with key \"%s\"\n", "" GCKEY);
        
        /* Get the default GConf proxy */
        gclient = gconf_client_get_default();
        g_assert(gclient != NULL);

        /* Get the value of GCKEY */
        val = gconf_client_get_string(gclient, "" GCKEY, NULL);
        if(val == NULL) {
                /* Key was not set before */
                val = g_strdup("<unset>");
        }
        g_assert(val != NULL);

        g_print("Initial value: \"%s\"\n", val);

        g_free(val);

        /* Watch GCPATH */
        gconf_client_add_dir(gclient, "" GCPATH, GCONF_CLIENT_PRELOAD_NONE, NULL);
        /* And specify a callback function for GCKEY changes */
        gconf_client_notify_add(gclient, "" GCKEY, key_changed_cb, NULL, NULL, NULL);

        /* Create a mainloop and run it */
        loop = g_main_loop_new(NULL, FALSE);
        g_assert(loop != NULL);
        g_main_loop_run(loop);

        return 0;
}

50% of this code is equal to "reader.c". The only "special" things is adding a callback notifier in main(), and the callback function itself.
You should notice GConfValues got a type: in this sample we check whether the key's type equals to "GCONF_VALUE_STRING", otherwise we don't "process" the value.

Once more, compile and run this code:

ikke@marslander ~/Projects/gconf $ gcc `pkg-config --libs --cflags gconf-2.0` -o listener listener.c
ikke@marslander ~/Projects/gconf $ ./listener
Working with key "/extra/test/key"
Initial value: "test2"

At this point, the program just hangs due to our GMainLoop. The key value is the one last set with ./setkey

Now open a new console, go to the directory where setkey is located, and execute it giving some new value. Then watch what's going on at the terminal where "listener" is running:

ikke@marslander ~/Projects/gconf $ ./setkey "a longer test key"
Working with key "/extra/test/key"
Value "a longer test key" set

In the "listener" console, we see this:

Value changed: "a longer test key"

Jay, change notifications working fine :-)

In this sample we only worked with string values, GConf also supports floats, integers, booleans, lists and even more. Check out the API docs for more information.
If you want to read more about GConf, e.g. its internals, you might want to check this tutorial by the GConf author, Havoc Pennington. Notice this is an old document, so the code samples in there won't work anymore, the GConf API has changed quite a lot since then. The ideas explained in the article are still relevant though, so it's worth reading.

Comments:

Comment from: Free Sprint Ringtone [Visitor] · http://free-ring-tones.awardspace.com
PermalinkPermalink 06/11/06 @ 08:36
Comment from: fashion jewelry [Visitor] · http://fashionjewelry.world-of-love.ru
Jewelry which in fashion today
choose fashion jewelry
Watch - how to buy and be top level
choose jewelry watch
PermalinkPermalink 06/29/06 @ 11:06
Comment from: Kerstin [Visitor] · http://www.telefonsex-sofort.de
thanks good work
PermalinkPermalink 07/12/06 @ 22:35

Leave a comment:

Your email address will not be displayed on this site.
Your URL will be displayed.

Allowed XHTML tags: <p, ul, ol, li, dl, dt, dd, address, blockquote, ins, del, span, bdo, br, em, strong, dfn, code, samp, kdb, var, cite, abbr, acronym, q, sub, sup, tt, i, b, big, small>
(Line breaks become <br />)
(Set cookies for name, email and url)
(Allow users to contact you through a message form (your email will NOT be displayed.))

Categories

Who's Online?

  • Guest Users: 475

Misc

XML Feeds

What is RSS?