Basic Usage

Let's look at PonG usage in a bit more detail. First off there are 3 basic file includes. The first is pong/pong.h this is the basic PonG library interface. Second is pong/pong-glade.h, which is the interface to the PonG module, and third the pong-bonobo/pong-bonobo.h which will pull in all the headers neccessary for the PonG bonobo functionality. So includes would look like this

Example 2. Includes example

#include <pong/pong.h>
#include <pong/pong-glade.h>
#include <pong-bonobo/pong-bonobo.h>

The first thing a program will do is initialize the library. This is not a memory or time intensive function, so it can safely be done at the beginning of the program, but it doesn't matter, you can just as well do it before your first use of PonG. The initializing function is called pong_init. Normally you might want to also enable some extra modules (plugs, more about that later) of PonG, such as the bonobo and/or glade modules. In that case you can also run pong_bonobo_init and pong_glade_init, that will set up the library to understand the bonobo and glade plugs. In that case make sure to use the pong_bonobo and pong_glade arguments to gnome-config, or just add glade and bonobo to the PONG_CHECK macro as described below. The initialization functions return a boolean which can indicate an error in initialization, that is, they return FALSE, if initialization of PonG failed. So you would do something like:

Example 3. Initializing

  if ( ! pong_init () || ! pong_glade_init () || ! pong_bonobo_init ()) {
    g_warning ("Initializing PonG failed!");
    exit (1);

After initialization, you will want to let PonG know the directory where your PonG files are stored. This is done with pong_add_directory which takes a single string argument with the directory. This will most likely come from your Makefile as a define, depending on the prefix that the user chose. If you are also using glade, you should also call pong_add_glade_directory. This will allow you (and the .pong files) to refer to .pong and .glade files by their basename only, making things look a lot neater, and more relocatable. Assuming that you made a define DATADIR which expands to the prefix of the data directory the application uses (say "/usr/share"), this could be a possible setup:

Example 4. Directories

  pong_add_directory (DATADIR "/application/pong/");
  pong_add_glade_directory (DATADIR "/application/glade/");

Now next thing you want to do is to load the file and show the dialog. This can be simply done with the pong_run_simple_dialog function. This takes a single argument which is the filename of the file to load and display. It returns a GtkWidget pointer of the dialog shown. It will return NULL, if it couldn't load a dialog from that file, so you should check for that condition too. You probably only want to show the dialog once, so you may want to do womething like this:

Example 5. Running the dialog

show_preferences (void)
  static GtkWidget *dialog = NULL;

  /* if the dialog exists, just show and raise it */
  if (dialog != NULL) {
    gtk_widget_show_now (dialog);
    gdk_window_raise (dialog->window);

  dialog = pong_run_simple_dialog ("mypongfile.pong");
  if (dialog == NULL) {
    g_warning ("Cannot load mypongfile.pong");
  } else {
    /* on destruction of the dialog, make the dialog
     * variable NULL again */
    gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
                        GTK_SIGNAL_FUNC (gtk_widget_destroyed), &dialog);

When you are done with using PonG and want the library to give up as much memory as possible you can call the pong_free_unused_data function, which takes no arguments. You can call this at any moment, what it does is clear any caches, or any other storage that can be easily rebuilt. This means that calling it is transparent, and only affect performance of PonG. A good idea is to bind the "destroy" signal of the dialog or the PongXML object (more on that in next section) and call this function from there.