static void
set_success (CalibArea *area)
{
  ClutterImage *image;
  GdkPixbuf *icon = area->icon_success;

  if (icon == NULL)
    return;

  image = CLUTTER_IMAGE (clutter_actor_get_content (area->success_image));
  clutter_image_set_data (image,
                          gdk_pixbuf_get_pixels (icon),
                          gdk_pixbuf_get_has_alpha (icon)
                          ? COGL_PIXEL_FORMAT_RGBA_8888
                          : COGL_PIXEL_FORMAT_RGB_888,
                          gdk_pixbuf_get_width (icon),
                          gdk_pixbuf_get_height (icon),
                          gdk_pixbuf_get_rowstride (icon),
                          NULL);
  clutter_actor_set_size (area->success_image,
                          gdk_pixbuf_get_width (icon),
                          gdk_pixbuf_get_height (icon));

  clutter_actor_show (area->success_image);
  clutter_actor_hide (area->action_layer);
}
Beispiel #2
0
static ClutterActor *
create_content_actor (void)
{
  ClutterActor *content;
  ClutterContent *image;
  GdkPixbuf *pixbuf;

  content = clutter_actor_new ();
  clutter_actor_set_size (content, 720, 720);

  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);

  clutter_actor_set_content_scaling_filters (content,
                                             CLUTTER_SCALING_FILTER_TRILINEAR,
                                             CLUTTER_SCALING_FILTER_LINEAR);
  clutter_actor_set_content_gravity (content, CLUTTER_CONTENT_GRAVITY_RESIZE_ASPECT);
  clutter_actor_set_content (content, image);
  g_object_unref (image);

  return content;
}
Beispiel #3
0
static ClutterActor* do_marker_icon (gchar *name, int size)
{
	GtkIconTheme *theme;
	GtkIconInfo *icon_info;
	GdkPixbuf *pixbuf;
	ClutterActor *ret;
	ClutterContent *icon;

	ret = clutter_actor_new ();

	theme = gtk_icon_theme_get_default ();
	icon_info = gtk_icon_theme_lookup_icon (theme, name, size, 0);
	if (icon_info != NULL) {
		pixbuf = gdk_pixbuf_new_from_file (gtk_icon_info_get_filename (icon_info), NULL);

		icon = clutter_image_new ();
		clutter_image_set_data (CLUTTER_IMAGE (icon),
					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);

		clutter_actor_set_content (ret, icon);
		g_object_unref (icon);
	}

	return ret;
}
gint
main (gint   argc,
      gchar *argv[])
{
   ClutterContent *image;
   ClutterActor *stage;
   ClutterActor *box;
   GdkPixbuf *pixbuf;

   if (clutter_init(&argc, &argv) != CLUTTER_INIT_SUCCESS) {
      g_printerr("Failed to initialize clutter.\n");
      return 1;
   }

   stage = clutter_stage_new();
   clutter_stage_set_title (CLUTTER_STAGE (stage), "Image Viewer");
   clutter_actor_set_size(stage, 1400, 1200);
   clutter_actor_set_position(stage, 100, 100);
   g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
   clutter_actor_show(stage);

   pixbuf = gdk_pixbuf_new_from_file("testimage_8000.png", NULL);
   g_assert(pixbuf);

   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);

   box = clutter_actor_new();
   clutter_actor_set_position(box, 0, 0);
   clutter_actor_set_height(box, 8000);
   clutter_actor_set_width(box, 1200);
   //clutter_actor_add_constraint(box, clutter_bind_constraint_new(stage, CLUTTER_BIND_WIDTH, 0.0));
   clutter_actor_set_content(box, image);
   clutter_actor_add_child(stage, box);
   clutter_actor_show(box);

   clutter_stage_set_fullscreen(CLUTTER_STAGE(stage), TRUE);

   clutter_actor_animate(box,
                         CLUTTER_EASE_IN_OUT_QUAD,
                         4000,
                         "y", -8000.0,
                         NULL);

   clutter_main();

   return 0;
}
Beispiel #5
0
/* Set an empty image of size 1x1 pixels (e.g. when loading asynchronously) */
static void _xfdashboard_image_content_set_empty_image(XfdashboardImageContent *self)
{
	static guchar		empty[]={ 0, 0, 0, 0xff };

	g_return_if_fail(XFDASHBOARD_IS_IMAGE_CONTENT(self));

	clutter_image_set_data(CLUTTER_IMAGE(self),
							empty,
							COGL_PIXEL_FORMAT_RGBA_8888,
							1, /* width */
							1, /* height */
							1, /* row-stride */
							NULL);
}
Beispiel #6
0
ClutterActor *
ckd_slide_new_for_image (GFile *file)
{
        CkdSlide *self = g_object_new (CKD_TYPE_SLIDE, NULL);
        CkdSlidePriv *priv = CKD_SLIDE_GET_PRIVATE (self);

        GdkPixbuf *pixbuf;
        ClutterContent *image;

        /* 载入图像数据 */
        gchar *image_path = g_file_get_path (file);
        pixbuf = gdk_pixbuf_new_from_file (image_path, NULL);

        /* 获取图像尺寸 */
        gfloat w = gdk_pixbuf_get_width (pixbuf);
        gfloat h = gdk_pixbuf_get_height (pixbuf);
        
        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,
                                (guint)w,
                                (guint)h,
                                gdk_pixbuf_get_rowstride (pixbuf),
                                NULL);
        g_object_unref (pixbuf);
        g_free (image_path);
                
        priv->content = clutter_actor_new ();

        clutter_actor_set_size (priv->content, w, h);
        clutter_actor_set_content_scaling_filters (priv->content,
                                                   CLUTTER_SCALING_FILTER_TRILINEAR,
                                                   CLUTTER_SCALING_FILTER_LINEAR);
        clutter_actor_set_content (priv->content, image);
        g_object_unref (image);
  

        clutter_actor_add_child (CLUTTER_ACTOR(self), priv->content);
        
        return (ClutterActor *)self;
}
Beispiel #7
0
static void
on_video_frame (GFreenectDevice *kinect, gpointer user_data)
{
  guchar *buffer;
  GError *error = NULL;
  GFreenectFrameMode frame_mode;
  ClutterContent *content;

  buffer = gfreenect_device_get_video_frame_rgb (kinect, NULL, &frame_mode);
  content = clutter_actor_get_content (video_tex);

  if (! clutter_image_set_data (CLUTTER_IMAGE (content),
                                buffer,
                                COGL_PIXEL_FORMAT_RGB_888,
                                frame_mode.width, frame_mode.height,
                                0,
                                &error))
    {
      g_debug ("Error setting texture area: %s", error->message);
      g_error_free (error);
    }
}
Beispiel #8
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;
}
Beispiel #9
0
/* Load image from file */
static void _xfdashboard_image_content_load_from_file(XfdashboardImageContent *self)
{
	XfdashboardImageContentPrivate		*priv;
	gchar								*lookupFilename;
	gchar								*filename;

	g_return_if_fail(XFDASHBOARD_IS_IMAGE_CONTENT(self));

	priv=self->priv;
	filename=NULL;

	/* Check if type of image is valid and all needed parameters are set */
	g_return_if_fail(priv->type==XFDASHBOARD_IMAGE_TYPE_FILE);
	g_return_if_fail(priv->iconName);
	g_return_if_fail(priv->iconSize>0);

	/* If path of icon filename is relative build absolute path by prefixing theme path ... */
	if(!g_path_is_absolute(priv->iconName))
	{
		XfdashboardTheme				*theme;
		const gchar						*themePath;

		/* Get theme path */
		theme=xfdashboard_application_get_theme();
		g_object_ref(theme);

		themePath=xfdashboard_theme_get_path(theme);

		/* Build absolute path from theme path and given relative path to icon */
		lookupFilename=g_build_filename(themePath, priv->iconName, NULL);

		/* Release allocated resources */
		g_object_unref(theme);
	}
		/* ... otherwise it is an absolute path already so just copy it */
		else lookupFilename=g_strdup(priv->iconName);

	/* If file does not exists then load fallback icon */
	if(!g_file_test(lookupFilename, G_FILE_TEST_EXISTS))
	{
		GtkIconInfo						*iconInfo;

		g_warning(_("Icon file '%s' does not exist - trying fallback icon '%s'"),
					priv->iconName,
					priv->missingIconName);

		iconInfo=gtk_icon_theme_lookup_icon(priv->iconTheme,
											priv->missingIconName,
											priv->iconSize,
#ifdef USE_GTK_BUILTIN_ICONS
											GTK_ICON_LOOKUP_USE_BUILTIN);
#else
											0);
#endif

		if(!iconInfo)
		{
			g_error(_("Could not load fallback icon for file '%s'"), priv->iconName);
			_xfdashboard_image_content_set_empty_image(self);
			g_free(lookupFilename);
			return;
		}

		/* Check if have to use built-in GdkPixbuf for icon ... */
		filename=g_strdup(gtk_icon_info_get_filename(iconInfo));
#ifdef USE_GTK_BUILTIN_ICONS
		if(!filename)
		{
			GdkPixbuf					*iconPixbuf;
			GError						*error=NULL;

			iconPixbuf=gtk_icon_info_get_builtin_pixbuf(iconInfo);
			if(!clutter_image_set_data(CLUTTER_IMAGE(self),
										gdk_pixbuf_get_pixels(iconPixbuf),
										gdk_pixbuf_get_has_alpha(iconPixbuf) ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888,
										gdk_pixbuf_get_width(iconPixbuf),
										gdk_pixbuf_get_height(iconPixbuf),
										gdk_pixbuf_get_rowstride(iconPixbuf),
										&error))
			{
				g_warning(_("Failed to load image data into content for icon '%s': %s"),
							priv->iconName,
							error ? error->message : _("Unknown error"));
				if(error)
				{
					g_error_free(error);
					error=NULL;
				}
			}
				else g_debug("Loaded fallback icon for file '%s' from built-in pixbuf", priv->iconName);

			g_object_unref(iconPixbuf);
		}
#endif

		/* Release allocated resources */
		g_object_unref(iconInfo);
	}
Beispiel #10
0
/* Callback when loading icon asynchronously has finished */
static void _xfdashboard_image_content_loading_async_callback(GObject *inSource, GAsyncResult *inResult, gpointer inUserData)
{
	XfdashboardImageContent				*self=XFDASHBOARD_IMAGE_CONTENT(inUserData);
	XfdashboardImageContentPrivate		*priv=self->priv;
	GdkPixbuf							*pixbuf;
	GError								*error=NULL;

	priv->loadState=XFDASHBOARD_IMAGE_CONTENT_LOADING_STATE_LOADED_SUCCESSFULLY;

	/* Get pixbuf loaded */
	pixbuf=gdk_pixbuf_new_from_stream_finish(inResult, &error);
	if(pixbuf)
	{
		/* Set image data into content */
		if(!clutter_image_set_data(CLUTTER_IMAGE(self),
									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),
									&error))
		{
			g_warning(_("Failed to load image data into content for key '%s': %s"),
						priv->key ? priv->key : "<nil>",
						error ? error->message : _("Unknown error"));
			if(error)
			{
				g_error_free(error);
				error=NULL;
			}

			/* Set failed state and empty image */
			_xfdashboard_image_content_set_empty_image(self);
			priv->loadState=XFDASHBOARD_IMAGE_CONTENT_LOADING_STATE_LOADED_FAILED;
		}
	}
		else
		{
			g_warning(_("Failed to load image for key '%s': %s"),
						priv->key ? priv->key : "<nil>",
						error ? error->message : _("Unknown error"));
			if(error)
			{
				g_error_free(error);
				error=NULL;
			}

			/* Set failed state and empty image */
			_xfdashboard_image_content_set_empty_image(self);
			priv->loadState=XFDASHBOARD_IMAGE_CONTENT_LOADING_STATE_LOADED_FAILED;
		}

	/* Release allocated resources */
	if(pixbuf) g_object_unref(pixbuf);

	/* Emit "loaded" signal if loading was successful ... */
	if(priv->loadState==XFDASHBOARD_IMAGE_CONTENT_LOADING_STATE_LOADED_SUCCESSFULLY)
	{
		g_signal_emit(self, XfdashboardImageContentSignals[SIGNAL_LOADED], 0);
		g_debug("Successfully loaded image for key '%s' asynchronously", priv->key ? priv->key : "<nil>");
	}
		/* ... or emit "loading-failed" signal if loading has failed. */
		else
		{
			g_signal_emit(self, XfdashboardImageContentSignals[SIGNAL_LOADING_FAILED], 0);
			g_debug("Failed to load image for key '%s' asynchronously", priv->key ? priv->key : "<nil>");
		}

	/* Now release the extra reference we took to keep this instance alive
	 * while loading asynchronously.
	 */
	g_object_unref(self);
}
static void 
image_rendered_cb (GInputStream *stream, GAsyncResult *res, RendererData *data)
{
  ChamplainTile *tile = data->tile;
  gboolean error = TRUE;
  GError *gerror = NULL;
  ClutterActor *actor = NULL;
  GdkPixbuf *pixbuf;
  ClutterContent *content;
  gfloat width, height;
  
  pixbuf = gdk_pixbuf_new_from_stream_finish (res, NULL);
  if (!pixbuf)
    {
      g_warning ("NULL pixbuf");
      goto finish;
    }
  
  /* Load the image into clutter */
  content = clutter_image_new ();
  if (!clutter_image_set_data (CLUTTER_IMAGE (content),
          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),
          &gerror))
    {
      if (gerror)
        {
          g_warning ("Unable to transfer to clutter: %s", gerror->message);
          g_error_free (gerror);
        }

      g_object_unref (content);
      goto finish;
    }

  clutter_content_get_preferred_size (content, &width, &height);
  actor = clutter_actor_new ();
  clutter_actor_set_size (actor, width, height);
  clutter_actor_set_content (actor, content);
  g_object_unref (content);
  /* has to be set for proper opacity */
  clutter_actor_set_offscreen_redirect (actor, CLUTTER_OFFSCREEN_REDIRECT_AUTOMATIC_FOR_OPACITY);
  
  error = FALSE;

finish:

  if (actor)
    champlain_tile_set_content (tile, actor);

  g_signal_emit_by_name (tile, "render-complete", data->data, data->size, error);

  if (pixbuf)
    g_object_unref (pixbuf);

  g_object_unref (data->renderer);
  g_object_unref (tile);
  g_object_unref (stream);
  g_free (data->data);
  g_slice_free (RendererData, data);
}
Beispiel #12
0
static void
on_depth_frame (GFreenectDevice *kinect, gpointer user_data)
{
  gboolean smoothing_enabled;
  gint width, height;
  gint dimension_factor;
  guchar *grayscale_buffer;
  guint16 *depth;
  BufferInfo *buffer_info;
  gsize len;
  GError *error = NULL;
  GFreenectFrameMode frame_mode;
  ClutterContent *content;

  depth = (guint16 *) gfreenect_device_get_depth_frame_raw (kinect,
                                                            &len,
                                                            &frame_mode);

  width = frame_mode.width;
  height = frame_mode.height;

  g_object_get (skeleton, "dimension-reduction", &dimension_factor, NULL);

  buffer_info = process_buffer (depth,
                                width,
                                height,
                                dimension_factor,
                                THRESHOLD_BEGIN,
                                THRESHOLD_END);

  skeltrack_skeleton_track_joints (skeleton,
                                   buffer_info->reduced_buffer,
                                   buffer_info->reduced_width,
                                   buffer_info->reduced_height,
                                   NULL,
                                   on_track_joints,
                                   buffer_info);


  content = clutter_actor_get_content (depth_tex);
  if (!SHOW_SKELETON)
    {
      grayscale_buffer = create_grayscale_buffer (buffer_info,
                                                  dimension_factor);

      if (depth_image == NULL)
        depth_image = clutter_image_new ();

      /* ref because we don't want it to be freed */
      if (depth_canvas == content)
        g_object_ref (depth_canvas);

      clutter_actor_set_content (depth_tex, depth_image);
      if (! clutter_image_set_data (CLUTTER_IMAGE (depth_image),
                                    grayscale_buffer,
                                    COGL_PIXEL_FORMAT_RGB_888,
                                    width, height,
                                    0,
                                    &error))
        {
          g_debug ("Error setting texture area: %s", error->message);
          g_error_free (error);
        }
      g_slice_free1 (width * height * sizeof (guchar) * 3, grayscale_buffer);
    }
  else {
    /* ref because we don't want it to be freed */
    if (depth_image && depth_image == content)
      g_object_ref (depth_image);

    clutter_actor_set_content (depth_tex, depth_canvas);
  }
}
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();

}
// handleNewFrame is the function that is called ever 120 milliseconds via the timeline!
// This is where ALL animation updates will happen.
void Animation::handleNewFrame(ClutterTimeline *timeline, gint frame_num, gpointer user_data) {

    // Rebuild the struct from the pointer we handed in:
    AnimationData *data;
    data = (AnimationData *) user_data;
    TCLControl *tcl = data->tcl; // tcl is STILL a pointer to the main TCLControl object
    Animation *animation = data->animationObject;

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

    shaderAnimation(tcl);

    // Send the updated color buffer to the strands
    if (tcl->enabled) {
        tcl->Update();
    }

    // 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);
    }
//    clutter_actor_set_content(lightDisplay, colors); // Bind that delegate to the lightDisplay


    // Update the shader uniforms:

    // Populate the audioImage with the FFT data:
//    executeFFT(audioPixels, audioRowstride);

    // Actually load our FFT Texture colors onto the actor
//    clutter_image_set_data (CLUTTER_IMAGE (audioImage),
//                            gdk_pixbuf_get_pixels (audiopixbuf),
//                            gdk_pixbuf_get_has_alpha (audiopixbuf)
//                            ? COGL_PIXEL_FORMAT_RGBA_8888
//                            : COGL_PIXEL_FORMAT_RGB_888,
//                            gdk_pixbuf_get_width (audiopixbuf),
//                            gdk_pixbuf_get_height (audiopixbuf),
//                            gdk_pixbuf_get_rowstride (audiopixbuf),
//                            &error);
//    clutter_actor_set_content (shaderOutput, audioImage);


    // Use the timeline delta to determine how much time to add to the clock:
    int delta = clutter_timeline_get_delta(timeline);
    if (animation->currentSpeed > 500 || animation->currentSpeed<-500) {
        animation->currentSpeed = 100;
    }
    animationTime += delta/1000.0 * (animation->currentSpeed/100.0);
//    printf("Current speed: %i, animation time: %f\n", animation->currentSpeed, animationTime);

    // Update the random noiseImage:
//    for (unsigned int i=0; i<noiseTextureSize; i++) {
//        noiseTexture[i] = getrandf();
//    }

    if (animation->shaderLoaded ) { // Only update the shader when a shader is actually SET
        clutter_shader_effect_set_uniform(CLUTTER_SHADER_EFFECT(shaderEffect), "iGlobalTime", G_TYPE_FLOAT, 1, animationTime);
        clutter_shader_effect_set_uniform(CLUTTER_SHADER_EFFECT(shaderEffect), "iMouse", G_TYPE_FLOAT, 2, input_y*1.0, input_x*1.0);
    }

}