I have been playing around with GTK+ for a few days when i have time spare, and I've learned to draw some simple 2D graphics with Cairo, i can get the graphic to render in a window, but how exactly do i re-draw based on events?
I've tried a few different things now, including attempting to use the
Code:
gtk_widget_queue_draw()
function, also tried to open a blank window and render the image only when the button is pressed, the program just crashes or does nothing.

I'm not great at C programming, or programming in general i suppose, but I'm trying to learn as much and as often as possible.

Here's the code i have so far.

Code:
#include <math.h>
#include <string.h>
#include <stdio.h>
#include <cairo.h>
#include <gtk/gtk.h>

struct m_struct {
    GtkWidget *window, *bx1, *bx2, *d_area, *button;
};



static void draw(GtkWidget *widget, cairo_t *cr, gpointer data);
static void redraw(GtkWidget *widget, cairo_t *cr, gpointer data);
static void click(struct m_struct *m);


static void draw(GtkWidget *widget, cairo_t *cr, gpointer data) {
    cairo_set_source_rgb(cr, 2, 5, 5);
    cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
    cairo_set_font_size(cr, 80.0);
    cairo_set_line_width (cr, 5);
    cairo_move_to(cr, 100, 275);
    cairo_line_to (cr, 100, 50);
    cairo_line_to (cr, 200, 50);
    cairo_line_to (cr, 200, 75);
    cairo_move_to(cr, 100, 275);
    cairo_line_to (cr, 150, 275);
    cairo_move_to(cr, 100, 275);
    cairo_line_to (cr, 50, 275);
    cairo_move_to(cr, 220, 95);
    cairo_arc(cr, 200, 95, 20, 0, 2 * M_PI);
    cairo_move_to(cr, 200, 115);
    cairo_line_to (cr, 200, 175);
    cairo_line_to (cr, 175, 200);
    cairo_move_to(cr, 200, 175);
    cairo_line_to (cr, 225, 200);
    cairo_move_to(cr, 200, 130);
    cairo_line_to (cr, 225, 150);
    cairo_move_to(cr, 200, 130);
    cairo_line_to (cr, 175, 150);
    cairo_stroke (cr);

}


static void redraw(GtkWidget *widget, cairo_t *cr, gpointer data) {
    cairo_set_source_rgb(cr, 2, 5, 5);
    cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
    cairo_set_font_size(cr, 80.0);
    cairo_set_line_width (cr, 5);
    cairo_move_to(cr, 100, 275);
    cairo_line_to (cr, 100, 50);
    cairo_line_to (cr, 200, 50);
    cairo_line_to (cr, 200, 75);
    cairo_move_to(cr, 100, 275);
    cairo_line_to (cr, 150, 275);
    cairo_stroke (cr);

}

static void click(struct m_struct *m) {
    g_signal_connect(m->d_area, "draw", G_CALLBACK(redraw), NULL);
}

int main(int argc, char *argv[]) {
    struct m_struct m;
    gtk_init(&argc, &argv);

    m.window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    m.bx1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, FALSE);
    m.bx2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, FALSE);

    m.d_area = gtk_drawing_area_new();

    m.button = gtk_button_new_with_label("Button");
    gtk_container_add(GTK_CONTAINER(m.window), m.bx1);
    gtk_box_pack_start(GTK_BOX(m.bx1), m.d_area, TRUE, TRUE, FALSE);
    gtk_box_pack_start(GTK_BOX(m.bx1), m.bx2, FALSE, FALSE, FALSE);
    gtk_box_pack_start(GTK_BOX(m.bx2), m.button, FALSE, FALSE, FALSE);
    g_signal_connect(m.window, "delete-event", G_CALLBACK(gtk_main_quit), NULL);
    g_signal_connect(m.button, "clicked", G_CALLBACK(click), &m);
    g_signal_connect(m.d_area, "draw", G_CALLBACK(draw), NULL);
    gtk_window_set_position(GTK_WINDOW(m.window), GTK_WIN_POS_CENTER);
    gtk_window_set_default_size(GTK_WINDOW(m.window), 275, 325);
    gtk_window_set_title(GTK_WINDOW(m.window), "DRAW");
    gtk_widget_show_all(m.window);

    gtk_main();

    return 0;
}
As is, the program crashes once the button is pressed, i would like it to re-draw to the window?

Would very much appreciate some suggestion as to how i should go about this.