示例#1
0
/**
 *	return number of frames per second and duration in msec
 */
gint 
pgpug_pixbuf_animation_get_detail (GdkPixbufAnimation *anim, gint *frames_count, gint *duration)
{
     //FIXME: there should be a better way to get frames count from animation     	       
     *frames_count = 0;
     *duration = 0;

     if (gdk_pixbuf_animation_is_static_image (anim)){
	  (*frames_count)++; 
	  return;
     }
     
     GTimeVal start_time = {0, 0};
     GdkPixbufAnimationIter *iter = gdk_pixbuf_animation_get_iter (anim, &start_time);
     GdkPixbuf *cur_frame, *first_frame = gdk_pixbuf_animation_iter_get_pixbuf (iter);
     int delay_time = gdk_pixbuf_animation_iter_get_delay_time (iter);

     while (delay_time > 0){

	  g_time_val_add (&start_time, delay_time*1000);

	  gboolean need_upd = gdk_pixbuf_animation_iter_advance (iter, &start_time);
	  if (need_upd){
	       (*frames_count)++; 
	       *duration += delay_time;
	  }

	  cur_frame = gdk_pixbuf_animation_iter_get_pixbuf (iter);
	  if (!need_upd || cur_frame == first_frame) {
	       delay_time = -1;
	  }
     }
     
     g_object_unref (iter);     
}
示例#2
0
static void
img_cell_renderer_anim_render( GtkCellRenderer      *cell,
							   GdkDrawable          *window,
							   GtkWidget            *widget,
							   GdkRectangle         *background_a,
							   GdkRectangle         *cell_a,
							   GdkRectangle         *expose_a,
							   GtkCellRendererState  state )
{
	ImgCellRendererAnimPrivate *priv;
	GdkPixbufAnimationIter     *iter;
	GdkPixbuf                  *pixbuf;
	cairo_t                    *cr;
	GdkRectangle                rect,
								draw_rect;

	priv = IMG_CELL_RENDERER_ANIM_GET_PRIVATE ( cell );

	/* Get image size */
	img_cell_renderer_anim_get_size( cell, widget, cell_a, &rect.x,
									 &rect.y, &rect.width, &rect.height );
	rect.x += cell_a->x + cell->xpad;
	rect.y += cell_a->y + cell->ypad;
	rect.width  -= 2 * cell->xpad;
	rect.height -= 2 * cell->ypad;

	/* Check for overlaping */
	if( ! gdk_rectangle_intersect( cell_a, &rect, &draw_rect ) ||
		! gdk_rectangle_intersect( expose_a, &draw_rect, &draw_rect ) )
		return;

	/* Draw indicators */
	cr = gdk_cairo_create( window );

	/* Draw the current frame of the GdkPixbufAnimation */
	iter = g_object_get_data( G_OBJECT( priv->anim ), "iter" );
	if( ! iter )
	{
		gint delay;

		/* Initialiize iter */
		iter = gdk_pixbuf_animation_get_iter( priv->anim, NULL );
		g_object_set_data_full( G_OBJECT( priv->anim ), "iter", iter,
								(GDestroyNotify)g_object_unref );

		/* Install timeout */
		delay = gdk_pixbuf_animation_iter_get_delay_time( iter );
		gdk_threads_add_timeout( delay, (GSourceFunc)cb_timeout, iter );
	}
	g_object_set_data( G_OBJECT( iter ), "widget", widget );
	pixbuf = gdk_pixbuf_animation_iter_get_pixbuf( iter );
	gdk_cairo_set_source_pixbuf( cr, pixbuf, rect.x, rect.y );
	gdk_cairo_rectangle( cr, &draw_rect );
	cairo_fill( cr );

	cairo_destroy( cr );
}
示例#3
0
	/* 
	   TODO: have image_fetcher tell us if it was a 404 and handle
	   that image here rather than there.
	 */
	void Image::on_image(const Glib::RefPtr<Gdk::PixbufLoader> &loader) {
		if (loader) {
			unscaled_image.reset();

			if (post->is_gif()) {
				unscaled_animation = loader->get_animation();
				if (unscaled_animation->is_static_image()) {
					unscaled_image = unscaled_animation->get_static_image();
					unscaled_animation.reset();
				} else {
					if (!animation_iter) {
						animation_time.assign_current_time();
						animation_iter = Glib::wrap(gdk_pixbuf_animation_get_iter(unscaled_animation->gobj(), &animation_time));

						animation_timeout = Glib::signal_timeout().connect(sigc::mem_fun(*this, &Image::on_animation_timeout),
						                                                   animation_iter->get_delay_time());
					}
					unscaled_image.reset();
					unscaled_image = animation_iter->get_pixbuf();
				}
			} else {
				unscaled_image = loader->get_pixbuf();
			}

			if (G_UNLIKELY(!unscaled_image)) {
				g_error("Received pixbuf image is null");
			}
			
			image->set(unscaled_image);
			image->show();
			show_all();
			image->queue_draw();
			refresh_size_request();

			if (is_changing_state) {
				is_changing_state = false;
				set_expand_state();
			}

			if (image_state == NONE)
				set_thumb_state();
		} else {
			std::cerr << "Warning: Horizon::Image got invalid PixbufLoader for"
			          << " image" << std::endl;
		}

		am_fetching_image = false;
	}
示例#4
0
	bool Image::on_image_draw(const Cairo::RefPtr< Cairo::Context > &) {
		if (unscaled_animation) {
			if (!animation_iter) {
				animation_time.assign_current_time();
				
				animation_iter = Glib::wrap(gdk_pixbuf_animation_get_iter(unscaled_animation->gobj(), &animation_time));
				unscaled_image.reset();
				unscaled_image = animation_iter->get_pixbuf();

				animation_timeout = Glib::signal_timeout().connect(sigc::mem_fun(*this, &Image::on_animation_timeout),
				                                                   animation_iter->get_delay_time());
			}
		}

		return false;
	}
示例#5
0
static gboolean ygtk_image_advance_frame_cb (gpointer data)
{
	YGtkImage *image = (YGtkImage *) data;
	struct _YGtkImageAnimation *animation = image->animation;

	if (!animation->frame)  // no frame yet loaded
		animation->frame = gdk_pixbuf_animation_get_iter (animation->pixbuf, NULL);
	else
		if (gdk_pixbuf_animation_iter_advance (animation->frame, NULL))
			gtk_widget_queue_draw (GTK_WIDGET (image));

	// shedule next frame
	int delay = gdk_pixbuf_animation_iter_get_delay_time (animation->frame);
	if (delay != -1)
		animation->timeout_id = g_timeout_add (delay, ygtk_image_advance_frame_cb, data);
	return FALSE;
}
示例#6
0
bool wxAnimationCtrl::Play()
{
    if (m_anim == NULL)
        return false;

    // init the iterator and start a one-shot timer
    ResetIter();
    m_iter = gdk_pixbuf_animation_get_iter (m_anim, NULL);
    m_bPlaying = true;

    // gdk_pixbuf_animation_iter_get_delay_time() may return -1 which means
    // that the timer should not start
    int n = gdk_pixbuf_animation_iter_get_delay_time(m_iter);
    if (n >= 0)
        m_timer.Start(n, true);

    return true;
}
示例#7
0
/* prepare frame information and register other callbacks */
static void
callback_area_prepared_anim (GdkPixbufLoader* loader)
{
    GdkPixbufAnimation *anim;
    FrameData* frame_copy = g_new (FrameData, 1);

    g_signal_connect (loader, "area-updated",
                      (GCallback) callback_area_updated_anim, (gpointer) frame_copy);
    g_signal_connect (loader, "closed",
                      (GCallback) callback_closed_anim, (gpointer) frame_copy);

    frame_copy->time.tv_sec = frame_copy->time.tv_usec = 0; /* some time */

    anim = gdk_pixbuf_loader_get_animation (loader);
    frame_copy->iter = gdk_pixbuf_animation_get_iter (anim, &frame_copy->time);
    frame_copy->pixbuf = gdk_pixbuf_copy (gdk_pixbuf_animation_iter_get_pixbuf (frame_copy->iter));
    update_currently_loaded_frame (frame_copy);
}
示例#8
0
static GdkPixbufAnimation*
compose_animation_from_array (animation_param_entry **anim_array, gint array_len, gint pix_size)
{
     GdkPixbufSimpleAnim *result = NULL;
     gint frames = 1, duration = 0,  duration_p, frames_p;
     /* calculate frames count as multiplication of all frames and duration as max */
     gint i;

     GTimeVal start_time = {0, 0};
     for (i = 0; i<array_len; i++){
	  /* initialize iterators for each animation*/
	  animation_param_entry *p_entry = anim_array[i];
	  
	  p_entry->iter = gdk_pixbuf_animation_get_iter (p_entry->anim, &start_time);
	  
	  frames_p = duration_p = 0;
	  pgpug_pixbuf_animation_get_detail (p_entry->anim, &frames_p, &duration_p);

	  duration = duration < duration_p ? duration_p : duration;
	  frames *= frames_p;
     }	  



     float fps = duration > 0 ? frames * 1000 / duration : 1;
     gint frame_change_time = duration / frames; 
     DEBG_MSG ("Fps: %f. frame change time :%dmsec", fps,frame_change_time);

     result = gdk_pixbuf_simple_anim_new (pix_size, pix_size, fps);
 
     gint elapsed_time = 0, frames_counter = 1;
     while (elapsed_time <= duration && frames_counter++ <= frames){

	  animation_param_entry *p_entry = anim_array[0];
	  GdkPixbuf *base_pixbuf = gdk_pixbuf_copy (gdk_pixbuf_animation_iter_get_pixbuf (p_entry->iter));
	  g_time_val_add (&start_time, frame_change_time * 1000);
	  gdk_pixbuf_animation_iter_advance (p_entry->iter, &start_time);

	  for (i = 1; i < array_len; i++) {
	       
	       p_entry = anim_array[i];
	       GdkPixbuf *src_pixbuf = gdk_pixbuf_animation_iter_get_pixbuf (p_entry->iter);
	       gint x_offset, y_offset, src_size;
	       src_size = gdk_pixbuf_get_width (src_pixbuf);

	       
	       pgpug_pixbuf_calculate_composition_offset (pix_size, src_size, p_entry->pos, &x_offset, &y_offset);

	       
	       gdk_pixbuf_composite (src_pixbuf, 
				     base_pixbuf,
				     x_offset, y_offset, 
				     src_size, src_size, 
				     x_offset, y_offset,
				     1.0f, 1.0f,
				     GDK_INTERP_BILINEAR, 255);
	       gboolean res;
	       res = gdk_pixbuf_animation_iter_advance (p_entry->iter, &start_time);
	       
	  }

	  gdk_pixbuf_simple_anim_add_frame (result, base_pixbuf);
	  elapsed_time += frame_change_time;
     }

     gdk_pixbuf_simple_anim_set_loop (result, TRUE);

     for (i=0;i<array_len;i++){
	  g_object_unref (anim_array[i]->iter);
     }

     return GDK_PIXBUF_ANIMATION (result);
}
示例#9
0
static GdkPixbuf *
_gdk_pixbuf_new_from_uri_at_scale (const char  *uri,
				   gint         size,
				   GError     **error)
{
    gboolean result;
    guchar buffer[LOAD_BUFFER_SIZE];
    gssize bytes_read;
    GdkPixbufLoader *loader = NULL;
    GdkPixbuf *pixbuf;	
    GdkPixbufAnimation *animation;
    GdkPixbufAnimationIter *iter;
    gboolean has_frame;
    SizePrepareContext info;
    GFile *file;
    GInputStream *input_stream;

    g_return_val_if_fail (uri != NULL, NULL);

    file = g_file_new_for_uri (uri);

    input_stream = G_INPUT_STREAM (g_file_read (file, NULL, error));
    if (input_stream == NULL) {
        g_object_unref (file);
        return NULL;
    }

    has_frame = FALSE;

    result = FALSE;
    while (!has_frame) {

	bytes_read = g_input_stream_read (input_stream,
					  buffer,
					  sizeof (buffer),
					  NULL,
					  error);
        if (bytes_read == -1) {
            break;
        }
	result = TRUE;
	if (bytes_read == 0) {
	    break;
	}

        if (loader == NULL) {
            loader = create_loader (file, buffer, bytes_read);
            if (1 <= size) {
              info.size = size;
              info.input_width = info.input_height = 0;
              g_signal_connect (loader, "size-prepared", G_CALLBACK (size_prepared_cb), &info);
            }
            g_assert (loader != NULL);
        }

	if (!gdk_pixbuf_loader_write (loader,
				      (unsigned char *)buffer,
				      bytes_read,
				      error)) {
	    result = FALSE;
	    break;
	}

	animation = gdk_pixbuf_loader_get_animation (loader);
	if (animation) {
		iter = gdk_pixbuf_animation_get_iter (animation, NULL);
		if (!gdk_pixbuf_animation_iter_on_currently_loading_frame (iter)) {
			has_frame = TRUE;
		}
		g_object_unref (iter);
	}
    }

    if (loader == NULL) {
        /* This can happen if the above loop was exited due to the
         * g_input_stream_read() call failing. */
        result = FALSE;
    } else if (*error != NULL) {
        gdk_pixbuf_loader_close (loader, NULL);
        result = FALSE;
    } else if (gdk_pixbuf_loader_close (loader, error) == FALSE) {
        if (!g_error_matches (*error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_INCOMPLETE_ANIMATION))
          result = FALSE;
        else
          g_clear_error (error);
    }

    if (!result) {
        g_clear_object (&loader);
	g_input_stream_close (input_stream, NULL, NULL);
	g_object_unref (input_stream);
	g_object_unref (file);
	return NULL;
    }

    g_input_stream_close (input_stream, NULL, NULL);
    g_object_unref (input_stream);
    g_object_unref (file);

    pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
    if (pixbuf != NULL) {
	g_object_ref (G_OBJECT (pixbuf));
	g_object_set_data (G_OBJECT (pixbuf), "gnome-original-width",
			   GINT_TO_POINTER (info.input_width));
	g_object_set_data (G_OBJECT (pixbuf), "gnome-original-height",
			   GINT_TO_POINTER (info.input_height));
    }
    g_object_unref (G_OBJECT (loader));

    return pixbuf;
}
示例#10
0
int main (int argc, char *argv[])
{

  if(argc > 1 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "-H")))
  {
    printf("Ponies for Linux/GTK+ by rabbit\n");
    printf("Command list:\n");
    printf("No Parameters: Run with the settings used from last run\n");
    printf("-h: Display this help\n");
    printf("file path: Set new file path to look for pony gif files\n");
    printf("ponyname: Sets to run one of the pony type listed\n");
    return 0;
  }

  for(int i = 1; i < argc; i++)
    if(*argv[i] == '/')
      setPonyDirectory(argv[i]);

  char* ponyDirectory = NULL;
  char* ponyHomeFile = NULL;

  ponyHomeFile = malloc((strlen(getenv("HOME"))+ 9) * sizeof(char));
  if(!ponyHomeFile)
  {
    printf("Could not allocate memory for ponyHomeFile\n");
    return 0;
  }
  strcpy(ponyHomeFile, getenv("HOME"));
  strcat(ponyHomeFile,"/.ponies");
  ponyDirectory = getPonyDirectory();

  if(!ponyDirectory)
  {
    free(ponyHomeFile);
    printf("Error locating pony directory\n");
    return 0;
  }

  //Initialize GTK+ and set up loggers
  GError* error = NULL;
  g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, (GLogFunc) gtk_false, NULL);
  gtk_init (&argc, &argv);
  g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, g_log_default_handler, NULL);

  //For command line commands later, require input on inital load
  //Normally would close, but hard coded in for easier testing
  int numberOfPonies = 0;
  if(argc == 1)
  {
    //Read in from ~/.ponies file to find saved settings
    FILE* ifp = NULL;
    char buffer[256];
    ifp = fopen(ponyHomeFile,"r");
    if(!ifp)
    {
      free(ponyHomeFile);
      free(ponyDirectory);
      printf("Could not open file for reading\n");
      return 0;
    }
    //fread(buffer, sizeof(char), 256, ifp);
    while(fgets(buffer, 256, ifp))
      if(buffer[0] != '\n')
        numberOfPonies++;

    fclose(ifp);
    numberOfPonies--;//First line is directory
  }
  //Not default arguments
  else
  {
    for(int i = 1; i < argc; i++)
    {
      if(*argv[i] == '/')
        continue;
      numberOfPonies++;
    }
  }

  //Seed the randomizer
  srand(time(0));

  //Number of ponies
  pony ponyArray[numberOfPonies];

  char buffer[256];
  FILE* ifp = NULL;
  ifp = fopen(ponyHomeFile,"r");
  if(!ifp)
  {
    printf("Could not open ~/.ponies\n");
    free(ponyDirectory);
    free(ponyHomeFile);
    return 0;
  }
  fgets(buffer, 256, ifp);//throw away first line

  //0 Ponies
  if(!numberOfPonies)
  {
    free(ponyDirectory);
    free(ponyHomeFile);
    printf("No ponies in the ~/.ponies file! Add some ponies!\n");
    printf("allowable ponies are: ");
    for(int i = 0; i <= Zecora; i++)
      printf("%s ", getDirectoryName(i));
    return 0;
  }


  //Make pony windows
  for( int i = 0; i < numberOfPonies; i++)
  {
    fgets(buffer, 256, ifp);
    char* temp = NULL;
    temp = strchr(buffer, '\n');
    if(temp)
      buffer[temp - buffer] = '\0';
    ponyArray[i].name = ponyNameFromString(buffer);
    ponyArray[i].direction = DirNone;
    ponyArray[i].dragActive = 0;
    ponyArray[i].speed = SpeedStopped;
    ponyArray[i].animation = AnimIdle;
    ponyArray[i].active = 1;
    ponyArray[i].facing = FaceLeft;
    //Create animation from file, default is idle_left
    char* initialPicturePath;
    initialPicturePath = malloc((strlen(ponyDirectory) +
                                 strlen(getDirectoryName(ponyArray[i].name)) +
                                 14) * sizeof(char));
    if(!initialPicturePath)
    {
      printf("Unable to allocate memory for directory");
      continue;
    }
    strcpy(initialPicturePath, ponyDirectory);
    strcat(initialPicturePath, getDirectoryName(ponyArray[i].name));
    strcat(initialPicturePath, "/idle_left.gif");
    ponyArray[i].pictureanim = gdk_pixbuf_animation_new_from_file
                              (initialPicturePath, &error);
    free(initialPicturePath);
    ponyArray[i].image = gtk_image_new_from_animation(ponyArray[i].pictureanim);
    ponyArray[i].pictureanimit = gdk_pixbuf_animation_get_iter
                                  (ponyArray[i].pictureanim, NULL);
    ponyArray[i].win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    //Resize everytime the gif updates
    g_timeout_add(gdk_pixbuf_animation_iter_get_delay_time(ponyArray[i].
                  pictureanimit),(GSourceFunc)updateWinSize, &ponyArray[i]);
    //Name the window the name of the pony being animated
    gtk_window_set_title(GTK_WINDOW(ponyArray[i].win),
                        getPonyName(ponyArray[i].name));
    //Size down the window before showing it
    gtk_window_set_default_size(GTK_WINDOW(ponyArray[i].win),
                                gdk_pixbuf_animation_get_width(ponyArray[i].
                                pictureanim), gdk_pixbuf_animation_get_height
                                (ponyArray[i].pictureanim));
    //Remove the titlebar
    gtk_window_set_decorated(GTK_WINDOW(ponyArray[i].win), FALSE);

    //Set up the signals
    ponyArray[i].clickEventID = g_signal_connect(G_OBJECT(ponyArray[i].win),
                                "button_press_event", G_CALLBACK(click_event),
                                &ponyArray[i]);
    ponyArray[i].enterEventID = g_signal_connect(G_OBJECT(ponyArray[i].win),
                                "enter-notify-event", G_CALLBACK(enter_event),
                                &ponyArray[i]);
    ponyArray[i].leaveEventID = g_signal_connect(G_OBJECT(ponyArray[i].win),
                                "leave-notify-event", G_CALLBACK(enter_event),
                                &ponyArray[i]);
    gtk_widget_add_events(ponyArray[i].win, GDK_BUTTON_PRESS_MASK);
    gtk_container_add(GTK_CONTAINER(ponyArray[i].win), GTK_WIDGET(ponyArray[i].
                                                                  image));

    //Get rid of taskbar item
    gtk_window_set_skip_taskbar_hint(GTK_WINDOW(ponyArray[i].win), TRUE);
    //Make it so it can't be selected
    gtk_window_set_accept_focus(GTK_WINDOW(ponyArray[i].win), FALSE);
    gtk_widget_realize(ponyArray[i].win);
    //Always on top
    gtk_window_set_keep_above(GTK_WINDOW(ponyArray[i].win), TRUE);
    updateWinSize(&ponyArray[i]);

    if(error != NULL)
      break;
  }
  free(ponyDirectory);
  free(ponyHomeFile);

  //Quit out if there were any errors and give a message
  if( error != NULL)
  {
      printf("%s\n",error->message);
      return 0;
  }



  //Make it transparent?
  /*cr = gdk_cairo_create(win->window);
  cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0);
  cairo_set_operator( cr, CAIRO_OPERATOR_SOURCE);
  cairo_paint(cr);
  gtk_container_add(GTK_CONTAINER(win), GTK_WIDGET(image));*/

  //Main loop
  for( int i = 0; i < numberOfPonies; i++)
    gtk_widget_show_all(ponyArray[i].win);
  gtk_main();
  return 0;
}
示例#11
0
void gaym_gtkconv_update_thumbnail(GaimConversation * conv, struct fetch_thumbnail_data
                                   *thumbnail_data)
{
    GaimGtkConversation *gtkconv;

    char filename[256];
    FILE *file;
    GError *err = NULL;

    size_t len;

    GdkPixbuf *buf;
    GdkPixbuf *scale;
    GdkPixmap *pm;
    GdkBitmap *bm;
    int scale_width, scale_height;


    GaimAccount *account;
    GaimPluginProtocolInfo *prpl_info = NULL;
    g_return_if_fail(conv != NULL);
    g_return_if_fail(GAIM_IS_GTK_CONVERSATION(conv));
    g_return_if_fail(gaim_conversation_get_type(conv) == GAIM_CONV_CHAT);

    gtkconv = GAIM_GTK_CONVERSATION(conv);

    GaymChatIcon *icon_data = g_hash_table_lookup(icons, conv);

    if (!thumbnail_data)
        return;
    if (!icon_data->show_icon)
        return;

    const char *data = thumbnail_data->pic_data;
    len = thumbnail_data->pic_data_len;

    account = gaim_conversation_get_account(conv);
    if (account && account->gc)
        prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(account->gc->prpl);


    if (icon_data->anim != NULL)
        g_object_unref(G_OBJECT(icon_data->anim));

    icon_data->anim = NULL;

    if (icon_data->icon_timer != 0)
        g_source_remove(icon_data->icon_timer);

    icon_data->icon_timer = 0;

    if (icon_data->iter != NULL)
        g_object_unref(G_OBJECT(icon_data->iter));

    icon_data->iter = NULL;

    if (!gaim_prefs_get_bool
        ("/gaim/gtk/conversations/im/show_buddy_icons"))
        return;

    if (gaim_conversation_get_gc(conv) == NULL)
        return;


    /* this is such an evil hack, i don't know why i'm even considering
       it. we'll do it differently when gdk-pixbuf-loader isn't leaky
       anymore. */
    /* gdk-pixbuf-loader was leaky? is it still? */

    g_snprintf(filename, sizeof(filename),
               "%s" G_DIR_SEPARATOR_S "gaimicon-%s.%d",
               g_get_tmp_dir(), thumbnail_data->who, getpid());

    if (!(file = g_fopen(filename, "wb")))
        return;

    fwrite(data, 1, len, file);
    fclose(file);
    icon_data->anim = gdk_pixbuf_animation_new_from_file(filename, &err);

    /* make sure we remove the file as soon as possible */
    g_unlink(filename);

    if (err) {
        gaim_debug(GAIM_DEBUG_ERROR, "gtkconv",
                   "Buddy icon error: %s\n", err->message);
        g_error_free(err);
    }



    if (!icon_data->anim)
        return;

    if (gdk_pixbuf_animation_is_static_image(icon_data->anim)) {
        icon_data->iter = NULL;
        buf = gdk_pixbuf_animation_get_static_image(icon_data->anim);
    } else {
        icon_data->iter = gdk_pixbuf_animation_get_iter(icon_data->anim, NULL); /* LEAK 
                                                                                 */
        buf = gdk_pixbuf_animation_iter_get_pixbuf(icon_data->iter);
    }

    get_icon_scale_size(icon_data->anim,
                        prpl_info ? &prpl_info->icon_spec : NULL,
                        &scale_width, &scale_height);
    scale =
        gdk_pixbuf_scale_simple(buf,
                                MAX(gdk_pixbuf_get_width(buf) *
                                    scale_width /
                                    gdk_pixbuf_animation_get_width
                                    (icon_data->anim), 1),
                                MAX(gdk_pixbuf_get_height(buf) *
                                    scale_height /
                                    gdk_pixbuf_animation_get_height
                                    (icon_data->anim), 1),
                                GDK_INTERP_NEAREST);

    gdk_pixbuf_render_pixmap_and_mask(scale, &pm, &bm, 100);
    g_object_unref(G_OBJECT(scale));


    icon_data->event = gtk_event_box_new();
    gtk_container_add(GTK_CONTAINER(icon_data->frame), icon_data->event);
    gtk_widget_set_size_request(GTK_WIDGET(icon_data->frame), scale_width,
                                scale_height);

    // g_signal_connect(G_OBJECT(icon_data->event), "button-press-event",
    // G_CALLBACK(icon_menu), conv);
    gtk_widget_show(icon_data->event);
    icon_data->icon = gtk_image_new_from_pixmap(pm, bm);
    gtk_container_add(GTK_CONTAINER(icon_data->event), icon_data->icon);
    gtk_widget_show(icon_data->icon);

    g_object_unref(G_OBJECT(pm));

    if (bm)
        g_object_unref(G_OBJECT(bm));


}
示例#12
0
/**
 * gnome_gdk_pixbuf_new_from_uri:
 * @uri: the uri of an image
 * @width: The width the image should have or -1 to not constrain the width
 * @height: The height the image should have or -1 to not constrain the height
 * @preserve_aspect_ratio: %TRUE to preserve the image's aspect ratio
 * 
 * Loads a GdkPixbuf from the image file @uri points to, scaling it to the
 * desired size. If you pass -1 for @width or @height then the value
 * specified in the file will be used.
 *
 * When preserving aspect ratio, if both height and width are set the size
 * is picked such that the scaled image fits in a width * height rectangle.
 * 
 * Return value: The loaded pixbuf, or NULL on error
 *
 * Since: 2.14
 **/
GdkPixbuf *
gnome_gdk_pixbuf_new_from_uri_at_scale (const char *uri,
					gint        width,
					gint        height,
					gboolean    preserve_aspect_ratio)
{
    GnomeVFSResult result;
    char buffer[LOAD_BUFFER_SIZE];
    GnomeVFSFileSize bytes_read;
    GdkPixbufLoader *loader;
    GdkPixbuf *pixbuf;	
    GdkPixbufAnimation *animation;
    GdkPixbufAnimationIter *iter;
    gboolean has_frame;
    SizePrepareContext info;
    GFile *file;
    GFileInputStream *file_input_stream;

    g_return_val_if_fail (uri != NULL, NULL);

    file = g_file_new_for_uri (uri);
    file_input_stream = g_file_read (file, NULL, NULL);
    if (file_input_stream == NULL) {
	g_object_unref (file);
	return NULL;
    }

    loader = gdk_pixbuf_loader_new ();
    if (1 <= width || 1 <= height) {
        info.width = width;
        info.height = height;
	info.input_width = info.input_height = 0;
        info.preserve_aspect_ratio = preserve_aspect_ratio;        
        g_signal_connect (loader, "size-prepared", G_CALLBACK (size_prepared_cb), &info);
    }

    has_frame = FALSE;

    result = GNOME_VFS_ERROR_GENERIC;
    while (!has_frame) {

	bytes_read = g_input_stream_read (G_INPUT_STREAM (file_input_stream),
					  buffer,
					  sizeof (buffer),
					  NULL,
					  NULL);
	if (bytes_read == -1) {
	    break;
	}
	result = GNOME_VFS_OK;
	if (bytes_read == 0) {
	    break;
	}

	if (!gdk_pixbuf_loader_write (loader,
				      (unsigned char *)buffer,
				      bytes_read,
				      NULL)) {
	    result = GNOME_VFS_ERROR_WRONG_FORMAT;
	    break;
	}

	animation = gdk_pixbuf_loader_get_animation (loader);
	if (animation) {
		iter = gdk_pixbuf_animation_get_iter (animation, NULL);
		if (!gdk_pixbuf_animation_iter_on_currently_loading_frame (iter)) {
			has_frame = TRUE;
		}
		g_object_unref (iter);
	}
    }

    gdk_pixbuf_loader_close (loader, NULL);
    
    if (result != GNOME_VFS_OK) {
	g_object_unref (G_OBJECT (loader));
	g_input_stream_close (G_INPUT_STREAM (file_input_stream), NULL, NULL);
	g_object_unref (file_input_stream);
	g_object_unref (file);
	return NULL;
    }

    g_input_stream_close (G_INPUT_STREAM (file_input_stream), NULL, NULL);
    g_object_unref (file_input_stream);
    g_object_unref (file);

    pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
    if (pixbuf != NULL) {
	g_object_ref (G_OBJECT (pixbuf));
	g_object_set_data (G_OBJECT (pixbuf), "gnome-original-width",
			   GINT_TO_POINTER (info.input_width));
	g_object_set_data (G_OBJECT (pixbuf), "gnome-original-height",
			   GINT_TO_POINTER (info.input_height));
    }
    g_object_unref (G_OBJECT (loader));

    return pixbuf;
}