static void load_async_thread (GSimpleAsyncResult *res, GObject *object, GCancellable *cancellable) { GLoadableIconIface *iface; GInputStream *stream; LoadData *data; GError *error = NULL; char *type = NULL; data = g_simple_async_result_get_op_res_gpointer (res); iface = G_LOADABLE_ICON_GET_IFACE (object); stream = iface->load (G_LOADABLE_ICON (object), data->size, &type, cancellable, &error); if (stream == NULL) { g_simple_async_result_take_error (res, error); } else { data->stream = stream; data->type = type; } }
static void test_serialize (void) { GError *error = NULL; GdkPixbuf *pixbuf; GdkPixbuf *pixbuf2; GVariant *data; GIcon *icon; GInputStream *stream; pixbuf = gdk_pixbuf_new_from_file (g_test_get_filename (G_TEST_DIST, "test-image.png", NULL), &error); g_assert_no_error (error); g_assert (pixbuf != NULL); /* turn it into a GVariant */ data = g_icon_serialize (G_ICON (pixbuf)); /* back to a GIcon, but this will be a GBytesIcon, not GdkPixbuf */ icon = g_icon_deserialize (data); g_assert (G_IS_BYTES_ICON (icon)); /* but since that is a GLoadableIcon, we can load it again */ stream = g_loadable_icon_load (G_LOADABLE_ICON (icon), 0, NULL, NULL, &error); g_assert_no_error (error); pixbuf2 = gdk_pixbuf_new_from_stream (stream, NULL, &error); g_assert_no_error (error); /* make sure that the pixels are the same. * our _serialize() uses png, so this should be perfect. */ { guchar *pixels_a, *pixels_b; guint len_a, len_b; pixels_a = gdk_pixbuf_get_pixels_with_length (pixbuf, &len_a); pixels_b = gdk_pixbuf_get_pixels_with_length (pixbuf2, &len_b); g_assert (len_a == len_b); g_assert (memcmp (pixels_a, pixels_b, len_a) == 0); } g_object_unref (pixbuf2); g_object_unref (pixbuf); g_object_unref (stream); g_variant_unref (data); }
static void avatar_icon_load_cb (GObject *object, GAsyncResult *result, gpointer user_data) { GLoadableIcon *icon = G_LOADABLE_ICON (object); PixbufAvatarFromIndividualClosure *closure = user_data; GInputStream *stream; GError *error = NULL; GdkPixbuf *pixbuf; GdkPixbuf *final_pixbuf; stream = g_loadable_icon_load_finish (icon, result, NULL, &error); if (error != NULL) { DEBUG ("Failed to open avatar stream: %s", error->message); g_simple_async_result_set_from_error (closure->result, error); goto out; } pixbuf = gdk_pixbuf_new_from_stream_at_scale (stream, closure->width, closure->height, TRUE, closure->cancellable, &error); g_object_unref (stream); if (pixbuf == NULL) { DEBUG ("Failed to read avatar: %s", error->message); g_simple_async_result_set_from_error (closure->result, error); goto out; } final_pixbuf = transform_pixbuf (pixbuf); /* Pass ownership of final_pixbuf to the result */ g_simple_async_result_set_op_res_gpointer (closure->result, final_pixbuf, g_object_unref); out: g_simple_async_result_complete (closure->result); g_clear_error (&error); pixbuf_avatar_from_individual_closure_free (closure); }
NautilusIconInfo * nautilus_icon_info_lookup (GIcon *icon, int size) { NautilusIconInfo *icon_info; GdkPixbuf *pixbuf; if (G_IS_LOADABLE_ICON (icon)) { LoadableIconKey lookup_key; LoadableIconKey *key; GInputStream *stream; if (loadable_icon_cache == NULL) { loadable_icon_cache = g_hash_table_new_full ((GHashFunc)loadable_icon_key_hash, (GEqualFunc)loadable_icon_key_equal, (GDestroyNotify) loadable_icon_key_free, (GDestroyNotify) g_object_unref); } lookup_key.icon = icon; lookup_key.size = size; icon_info = g_hash_table_lookup (loadable_icon_cache, &lookup_key); if (icon_info) { return g_object_ref (icon_info); } pixbuf = NULL; stream = g_loadable_icon_load (G_LOADABLE_ICON (icon), size, NULL, NULL, NULL); if (stream) { pixbuf = eel_gdk_pixbuf_load_from_stream_at_size (stream, size); g_object_unref (stream); } icon_info = nautilus_icon_info_new_for_pixbuf (pixbuf); key = loadable_icon_key_new (icon, size); g_hash_table_insert (loadable_icon_cache, key, icon_info); return g_object_ref (icon_info); } else if (G_IS_THEMED_ICON (icon)) { const char * const *names; ThemedIconKey lookup_key; ThemedIconKey *key; GtkIconTheme *icon_theme; GtkIconInfo *gtkicon_info; const char *filename; if (themed_icon_cache == NULL) { themed_icon_cache = g_hash_table_new_full ((GHashFunc)themed_icon_key_hash, (GEqualFunc)themed_icon_key_equal, (GDestroyNotify) themed_icon_key_free, (GDestroyNotify) g_object_unref); } names = g_themed_icon_get_names (G_THEMED_ICON (icon)); icon_theme = gtk_icon_theme_get_default (); gtkicon_info = gtk_icon_theme_choose_icon (icon_theme, (const char **)names, size, 0); if (gtkicon_info == NULL) { return nautilus_icon_info_new_for_pixbuf (NULL); } filename = gtk_icon_info_get_filename (gtkicon_info); lookup_key.filename = (char *)filename; lookup_key.size = size; icon_info = g_hash_table_lookup (themed_icon_cache, &lookup_key); if (icon_info) { gtk_icon_info_free (gtkicon_info); return g_object_ref (icon_info); } icon_info = nautilus_icon_info_new_for_icon_info (gtkicon_info); key = themed_icon_key_new (filename, size); g_hash_table_insert (themed_icon_cache, key, icon_info); gtk_icon_info_free (gtkicon_info); return g_object_ref (icon_info); } else { GdkPixbuf *pixbuf; GtkIconInfo *gtk_icon_info; gtk_icon_info = gtk_icon_theme_lookup_by_gicon (gtk_icon_theme_get_default (), icon, size, GTK_ICON_LOOKUP_GENERIC_FALLBACK); if (gtk_icon_info != NULL) { pixbuf = gtk_icon_info_load_icon (gtk_icon_info, NULL); gtk_icon_info_free (gtk_icon_info); } else { pixbuf = NULL; } return nautilus_icon_info_new_for_pixbuf (pixbuf); } }
NautilusIconInfo * nautilus_icon_info_lookup (GIcon *icon, int size) { NautilusIconInfo *icon_info; GdkPixbuf *pixbuf; if (G_IS_LOADABLE_ICON (icon)) { LoadableIconKey lookup_key; LoadableIconKey *key; GInputStream *stream; if (loadable_icon_cache == NULL) { loadable_icon_cache = g_hash_table_new_full ((GHashFunc)loadable_icon_key_hash, (GEqualFunc)loadable_icon_key_equal, (GDestroyNotify) loadable_icon_key_free, (GDestroyNotify) g_object_unref); } lookup_key.icon = icon; lookup_key.size = size; icon_info = g_hash_table_lookup (loadable_icon_cache, &lookup_key); if (icon_info) { return g_object_ref (icon_info); } pixbuf = NULL; stream = g_loadable_icon_load (G_LOADABLE_ICON (icon), size, NULL, NULL, NULL); if (stream) { GdkPixbuf *scaled_pixbuf; int w, h, s; double scale; pixbuf = eel_gdk_pixbuf_load_from_stream (stream); g_object_unref (stream); w = gdk_pixbuf_get_width (pixbuf); h = gdk_pixbuf_get_height (pixbuf); s = MAX (w, h); if (size != s) { scale = (double)size / s; scaled_pixbuf = gdk_pixbuf_scale_simple (pixbuf, w * scale, h * scale, GDK_INTERP_BILINEAR); g_object_unref (pixbuf); pixbuf = scaled_pixbuf; } } icon_info = nautilus_icon_info_new_for_pixbuf (pixbuf); key = loadable_icon_key_new (icon, size); g_hash_table_insert (loadable_icon_cache, key, icon_info); return g_object_ref (icon_info); } else if (G_IS_THEMED_ICON (icon)) { const char * const *names; ThemedIconKey lookup_key; ThemedIconKey *key; GtkIconTheme *icon_theme; GtkIconInfo *gtkicon_info; const char *filename; if (themed_icon_cache == NULL) { themed_icon_cache = g_hash_table_new_full ((GHashFunc)themed_icon_key_hash, (GEqualFunc)themed_icon_key_equal, (GDestroyNotify) themed_icon_key_free, (GDestroyNotify) g_object_unref); } names = g_themed_icon_get_names (G_THEMED_ICON (icon)); icon_theme = gtk_icon_theme_get_default (); gtkicon_info = gtk_icon_theme_choose_icon (icon_theme, (const char **)names, size, 0); if (gtkicon_info == NULL) { return nautilus_icon_info_new_for_pixbuf (NULL); } filename = gtk_icon_info_get_filename (gtkicon_info); lookup_key.filename = (char *)filename; lookup_key.size = size; icon_info = g_hash_table_lookup (themed_icon_cache, &lookup_key); if (icon_info) { gtk_icon_info_free (gtkicon_info); return g_object_ref (icon_info); } icon_info = nautilus_icon_info_new_for_icon_info (gtkicon_info); key = themed_icon_key_new (filename, size); g_hash_table_insert (themed_icon_cache, key, icon_info); gtk_icon_info_free (gtkicon_info); return g_object_ref (icon_info); } return nautilus_icon_info_new_for_pixbuf (NULL); }