static void on_pixbuf_loaded (GObject *source, GAsyncResult *result, gpointer user_data) { GSList *iter; StTextureCache *cache; AsyncTextureLoadData *data; GdkPixbuf *pixbuf; GError *error = NULL; CoglHandle texdata = NULL; data = user_data; cache = ST_TEXTURE_CACHE (source); g_hash_table_remove (cache->priv->outstanding_requests, data->key); pixbuf = load_pixbuf_async_finish (cache, result, &error); if (pixbuf == NULL) goto out; texdata = pixbuf_to_cogl_handle (pixbuf, data->enforced_square); g_object_unref (pixbuf); if (data->policy != ST_TEXTURE_CACHE_POLICY_NONE) { gpointer orig_key, value; if (!g_hash_table_lookup_extended (cache->priv->keyed_cache, data->key, &orig_key, &value)) { cogl_handle_ref (texdata); g_hash_table_insert (cache->priv->keyed_cache, g_strdup (data->key), texdata); } } for (iter = data->textures; iter; iter = iter->next) { ClutterTexture *texture = iter->data; set_texture_cogl_texture (texture, texdata); } out: if (texdata) cogl_handle_unref (texdata); texture_load_data_destroy (data); g_free (data); g_clear_error (&error); }
/** * st_texture_cache_load_from_data: * @cache: The texture cache instance * @data: Image data in PNG, GIF, etc format * @len: length of @data * @size: Size in pixels to use for the resulting texture * @error: Return location for error * * Synchronously creates an image from @data. The image is scaled down * to fit the available width and height dimensions, but the image is * never scaled up beyond its actual size. The pixbuf is rotated * according to the associated orientation setting. * * Return value: (transfer none): A new #ClutterActor with the image data loaded if it was * generated succesfully, %NULL otherwise */ ClutterActor * st_texture_cache_load_from_data (StTextureCache *cache, const guchar *data, gsize len, int size, GError **error) { ClutterTexture *texture; CoglHandle texdata; GdkPixbuf *pixbuf; char *key; char *checksum; texture = create_default_texture (cache); clutter_actor_set_size (CLUTTER_ACTOR (texture), size, size); checksum = g_compute_checksum_for_data (G_CHECKSUM_SHA1, data, len); key = g_strdup_printf (CACHE_PREFIX_COMPRESSED_CHECKSUM "checksum=%s,size=%d", checksum, size); g_free (checksum); texdata = g_hash_table_lookup (cache->priv->keyed_cache, key); if (texdata == NULL) { pixbuf = impl_load_pixbuf_data (data, len, size, size, error); if (!pixbuf) { g_object_unref (texture); g_free (key); return NULL; } texdata = pixbuf_to_cogl_handle (pixbuf); g_object_unref (pixbuf); set_texture_cogl_texture (texture, texdata); g_hash_table_insert (cache->priv->keyed_cache, g_strdup (key), texdata); } g_free (key); set_texture_cogl_texture (texture, texdata); return CLUTTER_ACTOR (texture); }
static ClutterActor * load_from_pixbuf (GdkPixbuf *pixbuf) { ClutterTexture *texture; CoglHandle texdata; int width = gdk_pixbuf_get_width (pixbuf); int height = gdk_pixbuf_get_height (pixbuf); texture = create_default_texture (); clutter_actor_set_size (CLUTTER_ACTOR (texture), width, height); texdata = pixbuf_to_cogl_handle (pixbuf, FALSE); set_texture_cogl_texture (texture, texdata); cogl_handle_unref (texdata); return CLUTTER_ACTOR (texture); }
static void finish_texture_load (AsyncTextureLoadData *data, GdkPixbuf *pixbuf) { GSList *iter; StTextureCache *cache; CoglHandle texdata = NULL; cache = data->cache; g_hash_table_remove (cache->priv->outstanding_requests, data->key); if (pixbuf == NULL) goto out; texdata = pixbuf_to_cogl_handle (pixbuf, data->enforced_square); if (data->policy != ST_TEXTURE_CACHE_POLICY_NONE) { gpointer orig_key, value; if (!g_hash_table_lookup_extended (cache->priv->keyed_cache, data->key, &orig_key, &value)) { cogl_handle_ref (texdata); g_hash_table_insert (cache->priv->keyed_cache, g_strdup (data->key), texdata); } } for (iter = data->textures; iter; iter = iter->next) { ClutterTexture *texture = iter->data; set_texture_cogl_texture (texture, texdata); } out: if (texdata) cogl_handle_unref (texdata); texture_load_data_free (data); }
static CoglHandle st_texture_cache_load_uri_sync_to_cogl_texture (StTextureCache *cache, StTextureCachePolicy policy, const gchar *uri, int available_width, int available_height, GError **error) { CoglHandle texdata; GdkPixbuf *pixbuf; char *key; key = g_strconcat (CACHE_PREFIX_URI, uri, NULL); texdata = g_hash_table_lookup (cache->priv->keyed_cache, key); if (texdata == NULL) { pixbuf = impl_load_pixbuf_file (uri, available_width, available_height, error); if (!pixbuf) goto out; texdata = pixbuf_to_cogl_handle (pixbuf, FALSE); g_object_unref (pixbuf); if (policy == ST_TEXTURE_CACHE_POLICY_FOREVER) { cogl_handle_ref (texdata); g_hash_table_insert (cache->priv->keyed_cache, g_strdup (key), texdata); } } else cogl_handle_ref (texdata); ensure_monitor_for_uri (cache, uri); out: g_free (key); return texdata; }
static void st_texture_cache_reset_texture (StTextureCachePropertyBind *bind, const char *propname) { GdkPixbuf *pixbuf; CoglHandle texdata; g_object_get (bind->source, propname, &pixbuf, NULL); g_return_if_fail (pixbuf == NULL || GDK_IS_PIXBUF (pixbuf)); if (pixbuf != NULL) { texdata = pixbuf_to_cogl_handle (pixbuf, FALSE); g_object_unref (pixbuf); clutter_texture_set_cogl_texture (bind->texture, texdata); cogl_handle_unref (texdata); clutter_actor_set_opacity (CLUTTER_ACTOR (bind->texture), 255); } else clutter_actor_set_opacity (CLUTTER_ACTOR (bind->texture), 0); }
static void on_pixbuf_loaded (GObject *source, GAsyncResult *result, gpointer user_data) { GSList *iter; StTextureCache *cache; AsyncTextureLoadData *data; GdkPixbuf *pixbuf; GError *error = NULL; CoglHandle texdata = NULL; data = user_data; cache = ST_TEXTURE_CACHE (source); g_hash_table_remove (cache->priv->outstanding_requests, data->key); pixbuf = load_pixbuf_async_finish (cache, result, &error); if (pixbuf == NULL) pixbuf = load_pixbuf_fallback (data); if (pixbuf == NULL) goto out; texdata = pixbuf_to_cogl_handle (pixbuf); g_object_unref (pixbuf); if (data->policy != ST_TEXTURE_CACHE_POLICY_NONE) { gpointer orig_key, value; if (!g_hash_table_lookup_extended (cache->priv->keyed_cache, data->key, &orig_key, &value)) { cogl_handle_ref (texdata); g_hash_table_insert (cache->priv->keyed_cache, g_strdup (data->key), texdata); } } for (iter = data->textures; iter; iter = iter->next) { ClutterTexture *texture = iter->data; set_texture_cogl_texture (texture, texdata); } out: if (texdata) cogl_handle_unref (texdata); g_free (data->key); if (data->icon) { gtk_icon_info_free (data->icon_info); g_object_unref (data->icon); } else if (data->uri) g_free (data->uri); if (data->recent_info) gtk_recent_info_unref (data->recent_info); if (data->mimetype) g_free (data->mimetype); /* Alternatively we could weakref and just do nothing if the texture is destroyed */ for (iter = data->textures; iter; iter = iter->next) { ClutterTexture *texture = iter->data; g_object_unref (texture); } g_clear_error (&error); g_free (data); }