Q:

GtkDrawingArea - how to make it drawable?

I'm going out of my mind a bit here. 
I'm trying to draw some simple graphics on my GTK form using cairo. 
#include <stdio.h>
#include <gtk/gtk.h>
#include <cairo.h>

GtkWidget* window;
GtkWidget* darea; 

int main(int argc, char **argv)
{
    gtk_init(&argc, &argv);     
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_default_size(GTK_WINDOW(window), 390, 240);

    darea = gtk_drawing_area_new();
    gtk_container_add(GTK_CONTAINER(window), darea); 

    cairo_t *cr; 
    cr = gdk_cairo_create(darea->window);
    cairo_rectangle(cr, 0, 0, 100, 100); 
    cairo_fill(cr);

    gtk_widget_show_all(window);

    gtk_main(); 

    return 0;
}

This compiles, but gives me  

Gdk-CRITICAL **: IA__gdk_cairo_create: assertion `GDK_IS_DRAWABLE
  (drawable)' failed

followed by a segfault. 
I've been looking at the tutorial here
So I changed my code as follows, made the cairo calls occur inside the expose event. 
    #include <stdio.h>
    #include <gtk/gtk.h>
    #include <cairo.h>

    GtkWidget* window;
    GtkWidget* darea; 

    static gboolean
    on_expose_event(GtkWidget *widget,
        GdkEventExpose *event,
        gpointer data)
    {
        cairo_t *cr; 
        cr = gdk_cairo_create(darea->window);
        cairo_rectangle(cr, 0, 0, 100, 100); 
        cairo_fill(cr);

    }    

    int main(int argc, char **argv)
    {
        gtk_init(&argc, &argv);     
        window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
        gtk_window_set_default_size(GTK_WINDOW(window), 390, 240);

        darea = gtk_drawing_area_new();
        gtk_container_add(GTK_CONTAINER(window), darea); 

        g_signal_connect(darea, "expose-event",
          G_CALLBACK(on_expose_event), NULL);

        gtk_widget_show_all(window);

        gtk_main(); 

        return 0;
    }

Why does this fix it? 
My understanding re: the expose is: 
the
g_signal_connect(darea, "expose-event", G_GCALLBACK(on_expose_event), NULL); 

tells the program, 'when an expose event happens to darea, then call on_expose_event'. The null is where you can pass in a pointer to a struct of additional information for the function to use. 
and 
    static gboolean
    on_expose_event(GtkWidget *widget,
        GdkEventExpose *event,
        gpointer data)
    {

means that on_expose_event is passed a pointer to the widget that the event happened to, andin this case because it's an expose event, a pointer to a struct containing information about the expose event, and a pointer to a struct to any other information you might like to add.

A:

Drawing on a widget with Cairo only works in an expose event. That is because Cairo is not like a vector drawing program where the lines and shapes are objects that are remembered and can be manipulated; Cairo just paints the shapes onto the drawing area and forgets about them.
So when you minimize and restore your window, or move another window over top of it, the shapes disappear. An expose event is generated to let you know that the shapes are gone and the widget needs to be redrawn. So you do your redrawing with Cairo in the expose event handler.

