Chinaunix首页 | 论坛 | 博客
  • 博客访问: 134173
  • 博文数量: 37
  • 博客积分: 2671
  • 博客等级: 少校
  • 技术积分: 335
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-11 13:18
文章分类

全部博文(37)

文章存档

2011年(16)

2010年(21)

我的朋友

分类: LINUX

2011-02-24 16:16:30

GConf

GConf is the configuration system of choice for GNOME 2 applications. It is replacing gnome-config, a very simple INI file based format, which turned out to be rather limited for large applications, and for handling advanced system-wide configuration by sysadmins. GConf on the other hand, is a lot more capable in those areas.

GConf was introduced in the GNOME 1.4 platform, but most GNOME applications didn't use it, with the most notable exception being Nautilus, the new GNOME file manager.

For GNOME 2 though, GConf is being rolled in more aggressively, with all (or at least most) of the core applications using GConf to store and manage their configuration data.

Advantages of GConf

There are numerous advantages to using GConf. The configuration data is stored in a tree structure, which makes it a lot easier to manage the preferences of a large application, which might have many preferences and configuration options.

An example of this tree structured configuration data might look like the following, taken from the web browser Galeon:

/apps/galeon:

/apps/galeon/Rendering:

/apps/galeon/Rendering/FontsColors:

background_color = #FFFFFF

visited_link_color = #FF0000

Here you see that Galeon is storing its preferences under the apps category, which is the place for applications to do so. Under the desktop category, on the other hand, desktop wide preferences, such as whether to use a left or right handed mouse, are stored.

Using subcategories, the preferences are split in small groups that belong together. This makes things clearer than just keeping all the options in one huge list, like the old-fashioned way dictated by gnome-config.

Data types

The kinds of data you can store in a GConf entry are: integer, string, float, boolean, schema, list, pair.

Most of these should be familiar to you, perhaps with the exception of schema, list and pair.

Schemas store a GConfSchema data type, which contains meta-information about a key. This will be described a bit more in detail further on in the article.

The list type stores a list of keys, although it has a few limitations. First all the elements must be of the same type, second, only the primitive types can be contained in a list (that is, all the types except list and pair).

Pairs can store two primitive values, either of the same type, or two different ones. Pairs can, like lists, only contain primitive types.

Notification

GConf offers another very nice feature for the modern desktop, namely notification across applications. This makes it possible for multiple applications, or multiple running instances of the same application, to immediately react to changes to preferences, and perform the necessary work to adapt to the new preferences.

In order to get notified of such a change, your application must tell GConf that it wants to listen to changes to a certain value, or to a whole directory in the configuration database.

Let's try all this out with a small example:(gconf-test.c)

  1. #include   
  2. #include   
  3. #include   
  4. #define PATH "/apps/GNOMEnclature/gconf_example"  
  5. #define KEY "/apps/GNOMEnclature/gconf_example/my_option"  
  6. static void  
  7. button_toggled_cb (GtkWidget *button, gpointer data)  
  8. {  
  9.     GConfClient *client = NULL;  
  10.     gboolean value;  
  11.     client = gconf_client_get_default ();  
  12.       
  13.     value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));  
  14.       
  15.     gconf_client_set_bool (client, KEY, value, NULL);  
  16. }  
  17. static void  
  18. gconf_notify_func (GConfClient *client,  
  19.                    guint cnxn_id,  
  20.                    GConfEntry *entry,  
  21.                    gpointer user_data)  
  22. {  
  23.     GtkWidget *check_button = GTK_WIDGET (user_data);  
  24.     GConfValue *value = NULL;  
  25.     gboolean checked;  
  26.       
  27.     value = gconf_entry_get_value (entry);  
  28.       
  29.     checked = gconf_value_get_bool (value);  
  30.       
  31.     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),  
  32.                                   checked);  
  33. }  
  34. int main (int argc, char *argv[])  
  35. {  
  36.     GtkWidget *window;  
  37.     GtkWidget *check_button;      
  38.     GConfClient *client;  
  39.     gboolean value;  
  40.       
  41.     gtk_init (&argc, &argv);  
  42.       
  43.     client = gconf_client_get_default ();  
  44.       
  45.     window = gtk_window_new (GTK_WINDOW_TOPLEVEL);  
  46.     g_signal_connect (window, "destroy", gtk_main_quit, NULL);  
  47.     value = gconf_client_get_bool (client, KEY, NULL);  
  48.       
  49.     check_button = gtk_check_button_new_with_label ("My Option");  
  50.     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button), value);  
  51.       
  52.     g_signal_connect (check_button, "toggled",   
  53.                       (GCallback)(button_toggled_cb), NULL);  
  54.       
  55.     gtk_container_add (GTK_CONTAINER (window), check_button);  
  56.     gtk_widget_show_all (window);  
  57.       
  58.     gconf_client_add_dir (client, PATH, GCONF_CLIENT_PRELOAD_NONE, NULL);  
  59.     gconf_client_notify_add (client, KEY, gconf_notify_func, check_button,  
  60.                              NULL, NULL);  
  61.     gtk_main ();      
  62.     return 0;  
  63. }  

Makefile:

  1. CFLAGS =  `pkg-config --cflags gtk+-2.0 glib-2.0 gconf-2.0` -g  
  2. LDFLAGS =  `pkg-config --libs gtk+-2.0 gconf-2.0` -rdynamic   
  3. SRC=gconf-test.c  
  4. test:$(SRC)  
  5.     $(CC) $(CFLAGS) $(LDFLAGS) $(SRC) -o test  

This example will popup a small window with a check button, that is connected to a GConf key. Try compiling the program, and start two instances of it, to see the notification service at work. When you check the button in one of the programs, it will immediately update the second program window as well! Also note that the state of the button is saved so the next time you start the program, it will be the same way as the last time you ran it.

Writing and using schema files

To use schemas with your application, you first need to create a schema file, which is an XML file, listing all the schemas. A simple example might look like:

  1.   
  2.     
  3.         
  4.         /schemas/apps/totem/lock_screensaver_on_audio  
  5.     /apps/totem/lock_screensaver_on_audio  
  6.     totem  
  7.     bool  
  8.     <default>truedefault>  
  9.     "C">  
  10.       <short>Allow the screensaver to activate even when audio-only is playingshort>  
  11.       <long>  
  12.         Allow the screensaver to activate even when audio-only is playing.  
  13.         This is useful for monitor powered speakers.  
  14.       long>  
  15.       
  16.         
  17.         
  18.         /schemas/apps/totem/open_path  
  19.     /apps/totem/open_path  
  20.     totem  
  21.     string  
  22.     <default>default>  
  23.     "C">  
  24.       <short>Default location for the "Open..." dialoguesshort>  
  25.       <long>Default location for the "Open..." dialogues, default is the current directorylong>  
  26.       
  27.         
  28.     
  29.   

As you can see, a schema file is simply a list of schemas. For each schema, you specify the type, default value, and which key the schema applies to. Make sure to add useful descriptions of the key, both the short and the long versions.

When you have your schema file, you can use gconftool to install it:

# gconftool --install-schema-file=FILENAME

If you want to read more about GConf, check out the API reference at: http://developer.gnome.org/doc/API/gconf/index.html .

阅读(1005) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~