GtkDrawingArea - как сделать его рисованным?

Я немного схожу с ума здесь.

Я пытаюсь нарисовать простую графику в моей форме GTK, используя 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;
}

Это компилируется, но дает мне

Gdk-CRITICAL **: IA__gdk_cairo_create: утверждение `GDK_IS_DRAWABLE (drawable) 'не выполнено

сопровождаемый segfault.

Я смотрел научебник здесь

Поэтому я изменил свой код следующим образом, чтобы вызовы cairo происходили внутри события expose.

    #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;
    }

Почему это исправить? Мое понимание: разоблачение:

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

сообщает программе: «когда событие expose происходит с darea, тогда вызывайте on_expose_event». Нулевое значение - это место, где вы можете передать указатель на структуру дополнительной информации, которую должна использовать функция.

а также

    static gboolean
    on_expose_event(GtkWidget *widget,
        GdkEventExpose *event,
        gpointer data)
    {

означает, что on_expose_event передается указатель на виджет, с которым произошло событие, и в этом случае, потому что это событие expose, указатель на структуру, содержащую информацию о событии expose, и указатель на структуру на любую другую информацию, которая может вам понравиться добавить.

Ответы на вопрос(2)

Ваш ответ на вопрос