21.2. The Anatomy Of A Widget

In order to create a new widget, it is important to have an understanding of how GTK objects work. This section is just meant as a brief overview. See the reference documentation for the details.

GTK widgets are implemented in an object oriented fashion. However, they are implemented in standard C. This greatly improves portability and stability over using current generation C++ compilers; however, it does mean that the widget writer has to pay attention to some of the implementation details. The information common to all instances of one class of widgets (e.g., to all Button widgets) is stored in the class structure. There is only one copy of this in which is stored information about the class's signals (which act like virtual functions in C). To support inheritance, the first field in the class structure must be a copy of the parent's class structure. The declaration of the class structure of GtkButtton looks like:

struct _GtkButtonClass
{
  GtkContainerClass parent_class;

  void (* pressed)  (GtkButton *button);
  void (* released) (GtkButton *button);
  void (* clicked)  (GtkButton *button);
  void (* enter)    (GtkButton *button);
  void (* leave)    (GtkButton *button);
};

When a button is treated as a container (for instance, when it is resized), its class structure can be cast to GtkContainerClass, and the relevant fields used to handle the signals.

There is also a structure for each widget that is created on a per-instance basis. This structure has fields to store information that is different for each instance of the widget. We'll call this structure the object structure. For the Button class, it looks like:

struct _GtkButton
{
  GtkContainer container;

  GtkWidget *child;

  guint in_button : 1;
  guint button_down : 1;
};

Note that, similar to the class structure, the first field is the object structure of the parent class, so that this structure can be cast to the parent class' object structure as needed.