In past chapters, you have been introduced to a number of interfaces including GtkCellEditable, GtkEditable, GtkFileChooser, GtkTreeModel, and GtkRecentChooser. Interfaces in GObject are very similar to those in Java. New interfaces are derived from GTypeInterface as shown in Listing 11-28.

Using Barcode maker for VS .NET Control to generate, create ECC200 image in .NET applications.

www.OnBarcode.com

Note The code in this section simply implements a very basic interface and object to illustrate what is necessary to use interfaces. For any practical purposes, it would need to be greatly expanded to include much more API.

Using Barcode generator for iPad Control to generate, create QR Code ISO/IEC18004 image in iPad applications.

www.OnBarcode.com

You will notice that the myiface.h header file contains much of the same functions and structures as when we were creating new widgets. There are four definitions; they return the interface s GType, cast the interface, check whether it is a valid GTK_TYPE_IFACE, and return the associated interface. When declaring interfaces, you must declare a type definition for the MyIFace structure, but this is merely an opaque type that allows MY_IFACE() to work. The MyIFaceInterface is the actual content of the interface. It should include a GTypeInterface object, which is the parent type of every interface. It also includes one or more function pointers. The programmer overrides these functions when an object implements the given interface. This allows each object to implement the interface in its own way, while still providing the consistency of naming across multiple objects.

static void my_iface_class_init (gpointer iface) { GType iface_type = G_TYPE_FROM_INTERFACE (iface); /* Install signals & properties here ... */ } void my_iface_print_message (MyIFace *obj, gchar *message) { MY_IFACE_GET_INTERFACE (obj)->print_message (obj, message); } The first function in Listing 11-29 is used to register the MyIFace type. This is done with g_type_register_static_simple(). It first accepts the GType corresponding to the parent and a name for the new type. The parent type is G_TYPE_INTERFACE for interfaces. The third parameter is the size of the interface structure, which can be obtained with the sizeof() function. GType g_type_register_static_simple (GType parent_type, const gchar *type_name, guint class_size, GClassInitFunc class_init, guint instance_size, GInstanceInitFunc instance_init, GTypeFlags flags); Next, you need to specify a class initialization function. Both the instance size and the instance initialization function can be ignored, since the instance structure is an opaque type. The last parameter is a bitwise field of GTypeFlags, which can safely be set to zero for interfaces. The other function, g_type_interface_add_prerequisite(), is used to force any object that implements the interface to also implement prerequisite_type. Interfaces can have only one prerequisite at most. void g_type_interface_add_prerequisite (GType interface_type, GType prerequisite_type); The class initialization function is similar to any other GObject class initialization function. It should be used to set up any signals and properties that are needed by the interface. Adding these to the interface means they will be available to any class that implements this interface. The last function, my_iface_print_message(), is a public function that simply calls the function located in the current MyIFaceInterface instance. This means that it will call the instance of the function that was added by the object that is implementing the interface.