static gboolean
on_timer_signal(CalibArea *area)
{
    GdkWindow *win;

    area->time_elapsed += TIME_STEP;
    if (area->time_elapsed > MAX_TIME)
    {
        set_calibration_status (area);
        return FALSE;
    }

    /* Update clock */
    win = gtk_widget_get_window (area->window);
    if (win)
    {
        GdkRectangle rect;
        rect.x = area->display_width/2 - CLOCK_RADIUS - CLOCK_LINE_WIDTH;
        rect.y = area->display_height/2 - CLOCK_RADIUS - CLOCK_LINE_WIDTH;
        rect.width = 2 * CLOCK_RADIUS + 1 + 2 * CLOCK_LINE_WIDTH;
        rect.height = 2 * CLOCK_RADIUS + 1 + 2 * CLOCK_LINE_WIDTH;
        gdk_window_invalidate_rect(win, &rect, FALSE);
    }

    return TRUE;
}
static gboolean
on_button_press_event(GtkWidget      *widget,
                      GdkEventButton *event,
                      CalibArea      *area)
{
    gboolean success;

    if (area->success)
        return FALSE;

    /* Check matching device ID if a device ID was provided */
    if (area->device_id > -1) {
        GdkDevice *device;

        device = gdk_event_get_source_device ((GdkEvent *) event);
        if (device != NULL && gdk_x11_device_get_id (device) != area->device_id)
	    return FALSE;
    }

    /* Handle click */
    area->time_elapsed = 0;
    success = add_click(&area->calibrator, (int)event->x_root, (int)event->y_root);

    if (!success && area->calibrator.num_clicks == 0)
        draw_message(area, N_("Mis-click detected, restarting..."));
    else
        draw_message(area, NULL);

    /* Are we done yet? */
    if (area->calibrator.num_clicks >= 4)
    {
        set_calibration_status (area);
        return FALSE;
    }

    /* Force a redraw */
    redraw(area);

    return FALSE;
}
static void
on_timeout (ClutterTimeline *timeline,
            CalibArea       *area)
{
  set_calibration_status (area);
}
static gboolean
on_button_press_event(ClutterActor       *actor,
                      ClutterButtonEvent *event,
                      CalibArea          *area)
{
  gint num_clicks;
  gboolean success;

  if (area->success)
    return FALSE;

  if (event->click_count > 1)
    return FALSE;

  /* Check matching device ID if a device ID was provided */
  if (area->device_id > -1)
    {
      ClutterInputDevice *device;

      device = clutter_event_get_source_device ((ClutterEvent *) event);
      if (device != NULL && clutter_input_device_get_device_id (device) != area->device_id) {
        char *name;

        g_object_get (G_OBJECT (device), "name", &name, NULL);
        g_debug ("Ignoring input from device %s (%d)",
                 name,
                 clutter_input_device_get_device_id (device));
        g_free (name);
        return FALSE;
      }
    }

  /* Handle click */
  clutter_timeline_stop (CLUTTER_TIMELINE (area->clock_timeline));
  clutter_timeline_start (CLUTTER_TIMELINE (area->clock_timeline));
  success = add_click(&area->calibrator,
                      (int) event->x,
                      (int) event->y);

  num_clicks = area->calibrator.num_clicks;

  if (!success && num_clicks == 0)
    show_error_message (area);
  else
    {
      gboolean visible;
      g_object_get (area->error_text, "visible", &visible, NULL);

      if (visible)
        hide_error_message (area);
    }

  /* Are we done yet? */
  if (num_clicks >= 4)
    {
      set_calibration_status (area);
      return FALSE;
    }

  cc_target_actor_move_center (CC_TARGET_ACTOR (area->target),
                               area->X[num_clicks],
                               area->Y[num_clicks]);

  return FALSE;
}