#include <gtk/gtk.h>

static gboolean
timeout (gpointer data)
{
  cairo_t *cr = gdk_cairo_create (data);

  g_print ("drawing dot\n\n");

  cairo_set_source_rgb (cr, g_random_double (),
                            g_random_double (),
                            g_random_double ());
  cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
  cairo_rectangle (cr, 5, 5, 5, 5);
  cairo_fill (cr);
  cairo_destroy (cr);

  return TRUE;
}

static gboolean
expose_event (GtkWidget *widget, GdkEventExpose *event)
{
  GdkWindow *window = widget->window;
  cairo_t *cr;

  printf ("expose on %s (%d %d %d %d)\n",
          (const char *) g_object_get_data (G_OBJECT (window), "debug-name"),
          event->area.x, event->area.y,
          event->area.width, event->area.height);

  cr = gdk_cairo_create (window);

  cairo_set_source_rgb (cr, g_random_double (),
                            g_random_double (),
                            g_random_double ());
  cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
  cairo_rectangle (cr, event->area.x, event->area.y,
                   event->area.width, event->area.height);
  cairo_fill (cr);
  cairo_destroy (cr);

  return TRUE;
}

int
main (void)
{
  GtkWidget *parent, *child, *grandchild, *button;

  gtk_init (NULL, NULL);

  parent = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  child = gtk_event_box_new ();
  grandchild = gtk_event_box_new ();
  button = gtk_button_new ();

  gtk_widget_set_size_request (button, 40, 40);

  gtk_container_set_border_width (GTK_CONTAINER (child), 20);
  gtk_container_set_border_width (GTK_CONTAINER (grandchild), 20);

  gtk_container_add (GTK_CONTAINER (grandchild), button);
  gtk_container_add (GTK_CONTAINER (child), grandchild);
  gtk_container_add (GTK_CONTAINER (parent), child);

  g_signal_connect (parent, "expose-event",
                    G_CALLBACK (expose_event), "parent");
  g_signal_connect (child, "expose-event",
                    G_CALLBACK (expose_event), "child");
  g_signal_connect (grandchild, "expose-event",
                    G_CALLBACK (expose_event), "grandchild");

  gtk_widget_show_all (parent);

  g_object_set_data (G_OBJECT (parent->window), "debug-name", "parent");
  g_object_set_data (G_OBJECT (child->window), "debug-name", "child");
  g_object_set_data (G_OBJECT (grandchild->window), "debug-name", "grandchild");
  g_object_set_data (G_OBJECT (button->window), "debug-name", "button");

  gdk_window_set_composited (child->window, TRUE);
  g_timeout_add (1000, timeout, button->window);

  gtk_main ();

  return 0;
}
