Exemple #1
0
int
main (int argc, char *argv[])
{
  ClutterActor *stage, *box, *bg, *icon, *emblem, *label;
  ClutterLayoutManager *layout;
  ClutterContent *canvas, *image;
  ClutterColor *color;
  ClutterAction *action;
  GdkPixbuf *pixbuf;

  if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
    return 1;

  /* prepare the stage */
  stage = clutter_stage_new ();
  clutter_stage_set_title (CLUTTER_STAGE (stage), "BinLayout");
  clutter_actor_set_background_color (stage, CLUTTER_COLOR_Aluminium2);
  clutter_actor_set_size (stage, 640, 480);
  clutter_actor_show (stage);
  g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);

  /* this is our BinLayout, with its default alignments */
  layout = clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_CENTER,
                                   CLUTTER_BIN_ALIGNMENT_CENTER);

  /* the main container; this actor will use the BinLayout to lay
   * out its children; we use the anchor point to keep it centered
   * on the same position even when we change its size
   */
  box = clutter_actor_new ();
  clutter_actor_set_layout_manager (box, layout);
  clutter_actor_add_constraint (box, clutter_align_constraint_new (stage, CLUTTER_ALIGN_BOTH, 0.5));
  clutter_actor_set_position (box, 320, 240);
  clutter_actor_set_reactive (box, TRUE);
  clutter_actor_set_name (box, "box");
  clutter_actor_add_child (stage, box);

  /* the background is drawn using a canvas content */
  canvas = clutter_canvas_new ();
  g_signal_connect (canvas, "draw", G_CALLBACK (on_canvas_draw), NULL);
  clutter_canvas_set_size (CLUTTER_CANVAS (canvas), 200, 200);

  /* this is the background actor; we want it to fill the whole
   * of the allocation given to it by its parent
   */
  bg = clutter_actor_new ();
  clutter_actor_set_name (bg, "background");
  clutter_actor_set_size (bg, 200, 200);
  clutter_actor_set_content (bg, canvas);
  clutter_actor_set_x_expand (bg, TRUE);
  clutter_actor_set_y_expand (bg, TRUE);
  clutter_actor_set_x_align (bg, CLUTTER_ACTOR_ALIGN_FILL);
  clutter_actor_set_y_align (bg, CLUTTER_ACTOR_ALIGN_FILL);
  clutter_actor_add_child (box, bg);
  /* we use the ::transitions-completed signal to get notification
   * of the end of the sizing animation; this allows us to redraw
   * the canvas only once the animation has stopped
   */
  g_signal_connect (box, "transitions-completed",
                    G_CALLBACK (redraw_canvas),
                    canvas);

  /* we use GdkPixbuf to load an image from our data directory */
  pixbuf = gdk_pixbuf_new_from_file (TESTS_DATADIR G_DIR_SEPARATOR_S "redhand.png", NULL);
  image = clutter_image_new ();
  clutter_image_set_data (CLUTTER_IMAGE (image),
                          gdk_pixbuf_get_pixels (pixbuf),
                          gdk_pixbuf_get_has_alpha (pixbuf)
                            ? COGL_PIXEL_FORMAT_RGBA_8888
                            : COGL_PIXEL_FORMAT_RGB_888,
                          gdk_pixbuf_get_width (pixbuf),
                          gdk_pixbuf_get_height (pixbuf),
                          gdk_pixbuf_get_rowstride (pixbuf),
                          NULL);
  g_object_unref (pixbuf);

  /* this is the icon; it's going to be centered inside the box actor.
   * we use the content gravity to keep the aspect ratio of the image,
   * and the scaling filters to get a better result when scaling the
   * image down.
   */
  icon = clutter_actor_new ();
  clutter_actor_set_name (icon, "icon");
  clutter_actor_set_size (icon, 196, 196);
  clutter_actor_set_x_expand (icon, TRUE);
  clutter_actor_set_y_expand (icon, TRUE);
  clutter_actor_set_x_align (icon, CLUTTER_ACTOR_ALIGN_CENTER);
  clutter_actor_set_y_align (icon, CLUTTER_ACTOR_ALIGN_CENTER);
  clutter_actor_set_content_gravity (icon, CLUTTER_CONTENT_GRAVITY_RESIZE_ASPECT);
  clutter_actor_set_content_scaling_filters (icon,
                                             CLUTTER_SCALING_FILTER_TRILINEAR,
                                             CLUTTER_SCALING_FILTER_LINEAR);
  clutter_actor_set_content (icon, image);
  clutter_actor_add_child (box, icon);

  color = clutter_color_new (g_random_int_range (0, 255),
                             g_random_int_range (0, 255),
                             g_random_int_range (0, 255),
                             224);

  /* this is the emblem: a small rectangle with a random color, that we
   * want to put in the bottom right corner
   */
  emblem = clutter_actor_new ();
  clutter_actor_set_name (emblem, "emblem");
  clutter_actor_set_size (emblem, 48, 48);
  clutter_actor_set_background_color (emblem, color);
  clutter_actor_set_x_expand (emblem, TRUE);
  clutter_actor_set_y_expand (emblem, TRUE);
  clutter_actor_set_x_align (emblem, CLUTTER_ACTOR_ALIGN_END);
  clutter_actor_set_y_align (emblem, CLUTTER_ACTOR_ALIGN_END);
  clutter_actor_set_reactive (emblem, TRUE);
  clutter_actor_set_opacity (emblem, 0);
  clutter_actor_add_child (box, emblem);
  clutter_color_free (color);

  /* when clicking on the emblem, we want to perform an action */
  action = clutter_click_action_new ();
  clutter_actor_add_action (emblem, action);
  g_signal_connect (action, "clicked", G_CALLBACK (on_emblem_clicked), box);
  g_signal_connect (action, "long-press", G_CALLBACK (on_emblem_long_press), box);

  /* whenever the pointer enters the box, we show the emblem; we hide
   * the emblem when the pointer leaves the box
   */
  g_signal_connect (box,
                    "enter-event", G_CALLBACK (on_box_enter),
                    emblem);
  g_signal_connect (box,
                    "leave-event", G_CALLBACK (on_box_leave),
                    emblem);

  /* a label, that we want to position at the top and center of the box */
  label = clutter_text_new ();
  clutter_actor_set_name (label, "text");
  clutter_text_set_text (CLUTTER_TEXT (label), "A simple test");
  clutter_actor_set_x_expand (label, TRUE);
  clutter_actor_set_x_align (label, CLUTTER_ACTOR_ALIGN_CENTER);
  clutter_actor_set_y_expand (label, TRUE);
  clutter_actor_set_y_align (label, CLUTTER_ACTOR_ALIGN_START);
  clutter_actor_add_child (box, label);

  clutter_main ();

  return EXIT_SUCCESS;
}
Exemple #2
0
int
main (int argc, char *argv[])
{
  ClutterActor *video;

  /* So we can fade out at the end. */
  clutter_x11_set_use_argb_visual (TRUE);

  if (clutter_gst_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
    return EXIT_FAILURE;

  if (argc < 2)
    {
      g_print ("Usage: %s [OPTIONS] <video file>\n", argv[0]);
      return EXIT_FAILURE;
    }

  if (!clutter_color_from_string (&bg_color, BG_COLOR))
    {
      g_warning ("Invalid BG_COLOR");
      exit (1);
    }

  stage = clutter_stage_new ();

  /* Clutter's full-screening code does not allow us to
   * set both that and _NET_WM_STATE_ABOVE, so do the state
   * management ourselves for now. */
#if 0
  clutter_stage_set_fullscreen (CLUTTER_STAGE (stage), TRUE);
#endif

  /* Clutter will set maximum size restrictions (meaning not
   * full screen) unless I set this. */
  clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE);

  clutter_stage_set_use_alpha (CLUTTER_STAGE (stage), TRUE);

  clutter_actor_set_background_color (stage, &bg_color);
  clutter_actor_set_layout_manager (stage,
                                    clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_FIXED,
                                                            CLUTTER_BIN_ALIGNMENT_FIXED));

  clutter_actor_realize (stage);
  set_above_and_fullscreen ();

  video = clutter_gst_video_texture_new ();
  clutter_actor_set_x_expand (video, TRUE);
  clutter_actor_set_y_expand (video, TRUE);
  clutter_actor_set_x_align (video, CLUTTER_ACTOR_ALIGN_CENTER);
  clutter_actor_set_y_align (video, CLUTTER_ACTOR_ALIGN_CENTER);
  set_idle_material (CLUTTER_GST_VIDEO_TEXTURE (video));

  g_signal_connect (video,
                    "eos",
                    G_CALLBACK (on_video_texture_eos),
                    NULL);

  g_signal_connect (stage,
                    "destroy",
                    G_CALLBACK (clutter_main_quit),
                    NULL);

  clutter_media_set_filename (CLUTTER_MEDIA (video), argv[1]);
  clutter_stage_hide_cursor (CLUTTER_STAGE (stage));

  clutter_actor_add_child (stage, video);

  g_signal_connect (stage, "key-press-event", G_CALLBACK (key_press_cb), NULL);

  clutter_media_set_playing (CLUTTER_MEDIA (video), TRUE);
  clutter_actor_show (stage);
  clutter_main ();

  return EXIT_SUCCESS;
}
int
main (int argc,
    char *argv[])
{
  GtkWidget *window;
  GtkWidget *widget, *vbox, *bbox, *button, *viewport, *image;
  ChamplainView *view;
  ChamplainMarkerLayer *layer;
  ClutterActor *scale;
  ChamplainLicense *license_actor;

  if (gtk_clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
    return 1;

  /* create the main, top level, window */
  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

  /* give the window a 10px wide border */
  gtk_container_set_border_width (GTK_CONTAINER (window), 10);

  /* give it the title */
  gtk_window_set_title (GTK_WINDOW (window), "libchamplain Gtk+ demo");

  /* Connect the destroy event of the window with our on_destroy function
   * When the window is about to be destroyed we get a notificaiton and
   * stop the main GTK loop
   */
  g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (on_destroy),
      NULL);

  vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);

  widget = gtk_champlain_embed_new ();
  view = gtk_champlain_embed_get_view (GTK_CHAMPLAIN_EMBED (widget));
  clutter_actor_set_reactive (CLUTTER_ACTOR (view), TRUE);
  g_signal_connect (view, "button-release-event", G_CALLBACK (mouse_click_cb), view);


  g_object_set (G_OBJECT (view),
      "kinetic-mode", TRUE,
      "zoom-level", 5,
      NULL);

  g_object_set_data (G_OBJECT (view), "window", window);
      
  scale = champlain_scale_new ();
  champlain_scale_connect_view (CHAMPLAIN_SCALE (scale), view);
  
  /* align to the bottom left */
  clutter_actor_set_x_expand (scale, TRUE);
  clutter_actor_set_y_expand (scale, TRUE);
  clutter_actor_set_x_align (scale, CLUTTER_ACTOR_ALIGN_START);
  clutter_actor_set_y_align (scale, CLUTTER_ACTOR_ALIGN_END);
  clutter_actor_add_child (CLUTTER_ACTOR (view), scale);
  
  license_actor = champlain_view_get_license_actor (view);
  champlain_license_set_extra_text (license_actor, "Don't eat cereals with orange juice\nIt tastes bad");
  
  champlain_view_center_on (CHAMPLAIN_VIEW (view), 45.466, -73.75);

  layer = create_marker_layer (view, &path);
  champlain_view_add_layer (view, CHAMPLAIN_LAYER (path));
  champlain_view_add_layer (view, CHAMPLAIN_LAYER (layer));
  
  path_layer = champlain_path_layer_new ();
  /* Cheap approx of Highway 10 */
  append_point (path_layer, 45.4095, -73.3197);
  append_point (path_layer, 45.4104, -73.2846);
  append_point (path_layer, 45.4178, -73.2239);
  append_point (path_layer, 45.4176, -73.2181);
  append_point (path_layer, 45.4151, -73.2126);
  append_point (path_layer, 45.4016, -73.1926);
  append_point (path_layer, 45.3994, -73.1877);
  append_point (path_layer, 45.4000, -73.1815);
  append_point (path_layer, 45.4151, -73.1218);
  champlain_view_add_layer (view, CHAMPLAIN_LAYER (path_layer));

  gtk_widget_set_size_request (widget, 640, 481);

  bbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
  button = gtk_button_new ();
  image = gtk_image_new_from_icon_name ("zoom-in", GTK_ICON_SIZE_BUTTON);
  gtk_button_set_image (GTK_BUTTON (button), image);
  gtk_button_set_label (GTK_BUTTON (button), "Zoom In");
  g_signal_connect (button, "clicked", G_CALLBACK (zoom_in), view);
  gtk_container_add (GTK_CONTAINER (bbox), button);

  button = gtk_button_new ();
  image = gtk_image_new_from_icon_name ("zoom-out", GTK_ICON_SIZE_BUTTON);
  gtk_button_set_image (GTK_BUTTON (button), image);
  gtk_button_set_label (GTK_BUTTON (button), "Zoom Out");
  g_signal_connect (button, "clicked", G_CALLBACK (zoom_out), view);
  gtk_container_add (GTK_CONTAINER (bbox), button);

  button = gtk_toggle_button_new_with_label ("Markers");
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
  g_signal_connect (button, "toggled", G_CALLBACK (toggle_layer), layer);
  gtk_container_add (GTK_CONTAINER (bbox), button);

  button = gtk_toggle_button_new_with_label ("Toggle wrap");
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
                                champlain_view_get_horizontal_wrap (view));
  g_signal_connect (button, "toggled", G_CALLBACK (toggle_wrap), view);
  gtk_container_add (GTK_CONTAINER (bbox), button);

  button = gtk_combo_box_new ();
  build_combo_box (GTK_COMBO_BOX (button));
  gtk_combo_box_set_active (GTK_COMBO_BOX (button), 0);
  g_signal_connect (button, "changed", G_CALLBACK (map_source_changed), view);
  gtk_container_add (GTK_CONTAINER (bbox), button);

  button = gtk_spin_button_new_with_range (0, 20, 1);
  gtk_spin_button_set_value (GTK_SPIN_BUTTON (button),
      champlain_view_get_zoom_level (view));
  g_signal_connect (button, "changed", G_CALLBACK (zoom_changed), view);
  g_signal_connect (view, "notify::zoom-level", G_CALLBACK (map_zoom_changed),
      button);
  gtk_container_add (GTK_CONTAINER (bbox), button);

  button = gtk_button_new ();
  image = gtk_image_new_from_icon_name ("list-add", GTK_ICON_SIZE_BUTTON);
  gtk_button_set_image (GTK_BUTTON (button), image);
  g_signal_connect (button, "clicked", G_CALLBACK (add_clicked), view);
  gtk_container_add (GTK_CONTAINER (bbox), button);

  button = gtk_button_new ();
  image = gtk_image_new_from_icon_name ("camera-photo-symbolic", GTK_ICON_SIZE_BUTTON);
  gtk_button_set_image (GTK_BUTTON (button), image);
  g_signal_connect (button, "clicked", G_CALLBACK (export_png), view);
  gtk_container_add (GTK_CONTAINER (bbox), button);

  button = gtk_image_new ();
  gtk_widget_set_size_request (button, 22, -1);
  g_signal_connect (view, "notify::state", G_CALLBACK (view_state_changed),
      button);
  gtk_box_pack_end (GTK_BOX (bbox), button, FALSE, FALSE, 0);

  viewport = gtk_frame_new (NULL);
  gtk_container_add (GTK_CONTAINER (viewport), widget);

  gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, FALSE, 0);
  gtk_container_add (GTK_CONTAINER (vbox), viewport);

  /* and insert it into the main window  */
  gtk_container_add (GTK_CONTAINER (window), vbox);

  /* make sure that everything, window and label, are visible */
  gtk_widget_show_all (window);
  /* start the main loop */
  gtk_main ();

  return 0;
}
Exemple #4
0
int
main (int argc, char *argv[])
{
  ClutterActor *stage, *box, *instructions;
  ClutterLayoutManager *stage_layout, *grid_layout;
  GError *error = NULL;

  if (clutter_init_with_args (&argc, &argv,
                              NULL,
                              entries,
                              NULL,
                              &error) != CLUTTER_INIT_SUCCESS)
    {
      g_print ("Unable to run grid-layout: %s", error->message);
      g_error_free (error);

      return EXIT_FAILURE;
    }

  stage = clutter_stage_new ();
  clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE);
  stage_layout = clutter_box_layout_new ();
  clutter_box_layout_set_orientation (CLUTTER_BOX_LAYOUT (stage_layout),
                                      CLUTTER_ORIENTATION_VERTICAL);
  clutter_actor_set_layout_manager (stage, stage_layout);

  grid_layout = clutter_grid_layout_new ();
  if (is_vertical)
    clutter_grid_layout_set_orientation (CLUTTER_GRID_LAYOUT (grid_layout),
                                         CLUTTER_ORIENTATION_VERTICAL);
  box = clutter_actor_new ();
  clutter_actor_set_background_color (box, CLUTTER_COLOR_LightGray);
  clutter_actor_set_x_expand (box, TRUE);
  clutter_actor_set_y_expand (box, TRUE);
  clutter_actor_set_layout_manager (box, grid_layout);
  clutter_actor_add_child (stage, box);
  clutter_actor_set_x_align (box, CLUTTER_ACTOR_ALIGN_FILL);
  clutter_actor_set_y_align (box, CLUTTER_ACTOR_ALIGN_FILL);

  add_actor (box, 0, 0, 1, 1);
  add_actor (box, 1, 0, 1, 1);
  add_actor (box, 2, 0, 1, 1);
  add_actor (box, 0, 1, 1, 1);
  add_actor (box, 1, 1, 2, 1);
  add_actor (box, 0, 2, 3, 1);
  add_actor (box, 0, 3, 2, 2);
  add_actor (box, 2, 3, 1, 1);
  add_actor (box, 2, 4, 1, 1);

  instructions = clutter_text_new_with_text ("Sans 12px", INSTRUCTIONS);
  clutter_actor_set_margin_top (instructions, 4);
  clutter_actor_set_margin_left (instructions, 4);
  clutter_actor_set_margin_bottom (instructions, 4);
  clutter_actor_add_child (stage, instructions);
  clutter_actor_set_x_align (instructions, CLUTTER_ACTOR_ALIGN_FILL);
  clutter_actor_set_y_align (instructions, CLUTTER_ACTOR_ALIGN_CENTER);

  g_signal_connect (stage, "destroy",
                    G_CALLBACK (clutter_main_quit), NULL);
  g_signal_connect (stage, "key-release-event",
                    G_CALLBACK (key_release_cb), box);

  clutter_actor_show (stage);

  clutter_main ();

  return 0;
}
Exemple #5
0
static void
add_actor (ClutterActor *box,
           gint          left,
           gint          top,
           gint          width,
           gint          height)
{
  ClutterLayoutManager *layout;
  ClutterActor *rect, *text;
  ClutterColor color;

  clutter_color_from_hls (&color,
                          g_random_double_range (0.0, 360.0),
                          0.5,
                          0.5);
  color.alpha = 255;

  rect = clutter_actor_new ();
  clutter_actor_set_layout_manager (rect, clutter_bin_layout_new ());
  clutter_actor_set_background_color (rect, &color);
  clutter_actor_set_reactive (rect, TRUE);

  if (random_size)
    clutter_actor_set_size (rect,
                            g_random_int_range (40, 80),
                            g_random_int_range (40, 80));
  else
    clutter_actor_set_size (rect, 60, 60);

  clutter_actor_set_x_expand (rect, default_expand);
  clutter_actor_set_y_expand (rect, default_expand);

  if (!default_expand)
    {
      clutter_actor_set_x_align (rect, CLUTTER_ACTOR_ALIGN_CENTER);
      clutter_actor_set_y_align (rect, CLUTTER_ACTOR_ALIGN_CENTER);
    }

  if (random_align)
    {
      clutter_actor_set_x_align (rect, g_random_int_range (0, 3));
      clutter_actor_set_y_align (rect, g_random_int_range (0, 3));
    }

  text = clutter_text_new_with_text ("Sans 8px", NULL);
  clutter_text_set_line_alignment (CLUTTER_TEXT (text),
                                   PANGO_ALIGN_CENTER);
  clutter_actor_add_child (rect, text);

  g_signal_connect (rect, "button-release-event",
                    G_CALLBACK (button_release_cb), NULL);
  g_signal_connect (rect, "notify::x-expand",
                    G_CALLBACK (changed_cb), text);
  g_signal_connect (rect, "notify::y-expand",
                    G_CALLBACK (changed_cb), text);
  g_signal_connect (rect, "notify::x-align",
                    G_CALLBACK (changed_cb), text);
  g_signal_connect (rect, "notify::y-align",
                    G_CALLBACK (changed_cb), text);

  layout = clutter_actor_get_layout_manager (box);
  if (use_box)
    clutter_actor_add_child (box, rect);
  else
    clutter_grid_layout_attach (CLUTTER_GRID_LAYOUT (layout), rect,
                                left, top, width, height);
  changed_cb (rect, NULL, text);
}
Animation::Animation(ClutterActor *stage, TCLControl *tcl) {
    printf("Building animation tools...\n");

    //====================
    // On screen display:

    // Build the Actor that will display what's going to the lights:
    lightDisplay = clutter_actor_new();

    // Build the color delegate for the lightDisplay's content/texture:
    colors = clutter_image_new();

    // Error object for GDK/Clutter calls that need them
    error = NULL;

    // Load image data from some other data source...:
    // guchar *data =
    // GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(data);

    // Load image data from a file:
//    const char *img_path = "./wut.png";
//    GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file_at_size (img_path, WIDTH, HEIGHT, &error);

    // Build the color buffer we'll store the actual colors in:
    pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, WIDTH, HEIGHT);
    pixels = gdk_pixbuf_get_pixels(pixbuf); // Grab it's pixels...
    rowstride = gdk_pixbuf_get_rowstride(pixbuf); // figure out the width of the buffer...

    // And put some RED into the buffer to start off with
    for (int x = 0; x < WIDTH; x++) {
        for (int y = 0; y < HEIGHT; y++) {

            // Find the ADDRESS of each pixel in the pixbuf via the raw char buffer we built...
            // and bind it to a pointer to a char...
            unsigned char *pixel = &pixels[y * rowstride + x * 3];

            // And directly update that memory location with a new color
            // This AUTOMATICALLY updates the color of the pixbuf!
            // It's just hitting the memory directly!
            pixel[0] = 255;//red
            pixel[1] = 0x0;//green
            pixel[2] = 0x0;//blue
        }
    }
    // Dump the colors from the color buffer into the ClutterContent delegate!
    if (pixbuf != NULL) {
        clutter_image_set_data(CLUTTER_IMAGE(colors),
                            gdk_pixbuf_get_pixels (pixbuf),
                            COGL_PIXEL_FORMAT_RGB_888,
                            gdk_pixbuf_get_width (pixbuf),
                            gdk_pixbuf_get_height (pixbuf),
                            gdk_pixbuf_get_rowstride (pixbuf),
                            &error);
    }

    // Tell the lightDisplay that it's content should be whatever we've dumped in the content delegate:
    clutter_actor_set_content(lightDisplay, colors);

    // Define the size of the On Screen Display:
    clutter_actor_set_x_expand(lightDisplay, TRUE);
    clutter_actor_set_y_expand(lightDisplay, TRUE);
    clutter_actor_set_position(lightDisplay, 0, WIDTH*(osd_scale+7)+WIDTH);
    clutter_actor_set_size(lightDisplay, WIDTH, HEIGHT);
    clutter_actor_set_scale(lightDisplay, osd_scale, osd_scale+7);
    clutter_actor_set_rotation_angle(lightDisplay, CLUTTER_Z_AXIS, -90);

    // Actually add that actor to the stage!
    clutter_actor_add_child(stage, lightDisplay);

    // Allow for UI events on this crazy thing!
    clutter_actor_set_reactive(lightDisplay, TRUE);

    // Wire up the event listener on this lightDisplay actor.
    TouchData *touch_data;
    touch_data = g_slice_new(TouchData); // reserve memory for it...
    touch_data->lightDisplay = lightDisplay; // Place the button actor itself inside the struct
    touch_data->tcl = tcl; // TCLControl *tcl is just a POINTER here (unlike in main.cpp)
    touch_data->animationNumber = &currentAnimation;

    // Actually wire up the events and set up the data structs that the events need to operate:
    g_signal_connect(lightDisplay, "touch-event", G_CALLBACK(handleTouchEvents), touch_data);
    g_signal_connect(lightDisplay, "button-press-event", G_CALLBACK(handleTouchEvents), touch_data);
    g_signal_connect(lightDisplay, "motion-event", G_CALLBACK(handleTouchEvents), touch_data);
    g_signal_connect(lightDisplay, "button-release-event", G_CALLBACK(handleTouchEvents), touch_data);

    // Set sane default values for the initial touch location
    input_y = 0;
    input_x = 0;

    // End On screen display
    //=============================
    // Shader setup and wirings:

    // Build the Actor that the shader will dump to directly:
    shaderOutput = clutter_actor_new();
    clutter_actor_set_position(shaderOutput, 0, 0);
    clutter_actor_set_size(shaderOutput, WIDTH-1, HEIGHT);
    clutter_actor_set_rotation_angle(shaderOutput, CLUTTER_Z_AXIS, -90);
    clutter_actor_set_rotation_angle(shaderOutput, CLUTTER_Y_AXIS, 180);
    clutter_actor_add_child(stage, shaderOutput);

    // Allocate the memory for the shader output buffer:
    // Figure out how big our buffer needs to be. *4 because four bytes per pixel (r, g, b, a) in shader land
    int shaderBufferSize = WIDTH * HEIGHT * 4;
    shaderBuffer = (guint8 *) malloc(shaderBufferSize); // malloc the buffer!!

    // Double check that we built the buffer correctly.
    if (shaderBuffer == NULL) {
        printf("OOPS! malloc error!\n");
    } else {
//        printf("We malloc'd %i bytes for your shaderBuffer. It points at: %p\n", shaderBufferSize, shaderBuffer);
//        printf(" The Rowstride on the shaderBuffer is %i\n", rowstride);
    }


    // init shader TEXTURES!
    // Populate the noiseImage:
//    const char *textureFile = "images/text_noise.png";
//    audiopixbuf = gdk_pixbuf_new_from_file (textureFile, NULL);


    // Init the audioImage that will store the FFT output for attaching to the actor
    error = NULL;
    audioImage = clutter_image_new ();
    audiopixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, WIDTH, HEIGHT );
    audioPixels = gdk_pixbuf_get_pixels(audiopixbuf); // Grab it's pixels...
    audioRowstride = gdk_pixbuf_get_rowstride(audiopixbuf); // figure out the width of the buffer...

    // Populate the audioImage with no data so we have a fresh start:
    for (int x = 0; x < WIDTH; x++) {
        for (int y = 0; y < HEIGHT; y++) {

            // Find the ADDRESS of each pixel in the pixbuf via the raw char buffer we built...
            // and bind it to a pointer to a char...
            unsigned char *pixel = &audioPixels[y * audioRowstride + x * 3];

            // And directly update that memory location with a new color
            // This AUTOMATICALLY updates the color of the pixbuf!
            // It's just hitting the memory directly!
            pixel[0] = getrand(0,255);//((int)(samples[x]*max)) & 0xff;   // low bits...
            pixel[1] = getrand(0,255);//((int)(samples[x]*max)) & 0xff00; // high bits.
            pixel[2] = getrand(0,255);     // some random value could be used for noise...
        }
    }

    // Actually load our color onto the actor
    clutter_image_set_data (CLUTTER_IMAGE (audioImage),
                            gdk_pixbuf_get_pixels (audiopixbuf),
                            COGL_PIXEL_FORMAT_RGB_888,
                            gdk_pixbuf_get_width (audiopixbuf),
                            gdk_pixbuf_get_height (audiopixbuf),
                            gdk_pixbuf_get_rowstride (audiopixbuf),
                            &error);
//    g_object_unref (audiopixbuf); // we want to reuse this... don't dereference that memory yet...
    clutter_actor_set_content (shaderOutput, audioImage);
    //clutter_actor_set_content_gravity (shaderOutput, CLUTTER_CONTENT_GRAVITY_TOP_RIGHT);

//    audioTexture[0] = 0.25;
//    srand(time(NULL));
//    for (i=0; i<noiseTextureSize; i++) {
//        noiseTexture[i] = getrandf();
//    }

    // Make sure we don't have a current shader so we don't break the update loop:
    shaderLoaded = false;
    currentSpeed = 100;




    // Once we have all that set up, we still need to START THE ACTUAL ANIMATION!!
    // To do that, we'll need to use the event chain/callback system we have been using so far.
    // Get ready to hand this display chunk in to the animation event:
    AnimationData *data;
    data = g_slice_new(AnimationData); // reserve memory for it...
    data->tcl = tcl; // tcl is an pointer to the main TCLControl object.
    data->animationNumber = &currentAnimation;
    data->animationObject = this;

    // The clutter timeline object takes a "duration" in milliseconds...
    timeline = clutter_timeline_new(1);
    g_signal_connect(timeline, "new-frame", G_CALLBACK(handleNewFrame), data);

    // which will just continue repeating:
    clutter_timeline_set_repeat_count(timeline, -1);

    // This actually starts the timeline animation!
    clutter_timeline_start(timeline);

    // Generate the list of known shaders:
    buildShaderList();

    // Load the first shader so we do not get a black screen:
    currentShader = 0; // Set the inital shader to load (usually, first in the directory)
    updateCurrentShader();

}