static void files_changed_cb (GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent event_type, gpointer user_data) { BgPicturesSource *self = BG_PICTURES_SOURCE (user_data); char *uri; switch (event_type) { case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: file_added (file, self); break; case G_FILE_MONITOR_EVENT_DELETED: uri = g_file_get_uri (file); bg_pictures_source_remove (self, uri); g_free (uri); break; default: return; } }
static void picture_opened_for_read (GObject *source_object, GAsyncResult *res, gpointer user_data) { BgPicturesSource *bg_source = BG_PICTURES_SOURCE (user_data); CcBackgroundItem *item; GFileInputStream *stream; GError *error = NULL; item = g_object_get_data (source_object, "item"); stream = g_file_read_finish (G_FILE (source_object), res, &error); if (stream == NULL) { char *filename; filename = g_file_get_path (G_FILE (source_object)); g_warning ("Failed to load picture '%s': %s", filename, error->message); g_free (filename); g_error_free (error); g_object_unref (item); return; } g_object_set_data (G_OBJECT (stream), "item", item); gdk_pixbuf_new_from_stream_at_scale_async (G_INPUT_STREAM (stream), THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, TRUE, NULL, picture_scaled, bg_source); g_object_unref (stream); }
static void file_info_ready (GObject *object, GAsyncResult *res, gpointer user_data) { GFileInfo *info; GError *error = NULL; GFile *file = G_FILE (object); info = g_file_query_info_finish (file, res, &error); if (!info) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("Problem looking up file info: %s", error->message); g_clear_error (&error); return; } /* Up the ref count so we can re-use the add_single_item code path which * reduces the ref count. */ g_object_ref (file); add_single_file_from_info (BG_PICTURES_SOURCE (user_data), file, info, NULL); }
static void dir_enum_async_ready (GObject *source, GAsyncResult *res, gpointer user_data) { BgPicturesSourcePrivate *priv; GFileEnumerator *enumerator; GError *err = NULL; enumerator = g_file_enumerate_children_finish (G_FILE (source), res, &err); if (err) { if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("Could not fill pictures source: %s", err->message); g_error_free (err); return; } priv = BG_PICTURES_SOURCE (user_data)->priv; /* get the files */ g_file_enumerator_next_files_async (enumerator, G_MAXINT, G_PRIORITY_LOW, priv->cancellable, file_info_async_ready, user_data); g_object_unref (enumerator); }
static void picture_scaled (GObject *source_object, GAsyncResult *res, gpointer user_data) { BgPicturesSource *bg_source; CcBackgroundItem *item; GError *error = NULL; GdkPixbuf *pixbuf; const char *software; const char *uri; GtkTreeIter iter; GtkListStore *store; pixbuf = gdk_pixbuf_new_from_stream_finish (res, &error); if (pixbuf == NULL) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("Failed to load image: %s", error->message); g_error_free (error); return; } /* since we were not cancelled, we can now cast user_data * back to BgPicturesSource. */ bg_source = BG_PICTURES_SOURCE (user_data); store = bg_source_get_liststore (BG_SOURCE (bg_source)); item = g_object_get_data (source_object, "item"); uri = cc_background_item_get_uri (item); /* Ignore screenshots */ software = gdk_pixbuf_get_option (pixbuf, "tEXt::Software"); if (software != NULL && g_str_equal (software, "gnome-screenshot")) { g_debug ("Ignored URL '%s' as it's a screenshot from gnome-screenshot", cc_background_item_get_uri (item)); g_object_unref (pixbuf); g_object_unref (item); return; } cc_background_item_load (item, NULL); /* insert the item into the liststore */ gtk_list_store_insert_with_values (store, &iter, -1, 0, pixbuf, 1, item, -1); g_hash_table_insert (bg_source->priv->known_items, bg_pictures_source_get_unique_filename (uri), GINT_TO_POINTER (TRUE)); g_object_unref (pixbuf); }
static void picture_opened_for_read (GObject *source_object, GAsyncResult *res, gpointer user_data) { BgPicturesSource *bg_source; CcBackgroundItem *item; GFileInputStream *stream; GError *error = NULL; gint thumbnail_height; gint thumbnail_width; item = g_object_get_data (source_object, "item"); stream = g_file_read_finish (G_FILE (source_object), res, &error); if (stream == NULL) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { char *filename = g_file_get_path (G_FILE (source_object)); g_warning ("Failed to load picture '%s': %s", filename, error->message); remove_placeholder (BG_PICTURES_SOURCE (user_data), item); g_free (filename); } g_error_free (error); return; } /* since we were not cancelled, we can now cast user_data * back to BgPicturesSource. */ bg_source = BG_PICTURES_SOURCE (user_data); thumbnail_height = bg_source_get_thumbnail_height (BG_SOURCE (bg_source)); thumbnail_width = bg_source_get_thumbnail_width (BG_SOURCE (bg_source)); g_object_set_data_full (G_OBJECT (stream), "item", g_object_ref (item), g_object_unref); gdk_pixbuf_new_from_stream_at_scale_async (G_INPUT_STREAM (stream), thumbnail_width, thumbnail_height, TRUE, bg_source->priv->cancellable, picture_scaled, bg_source); g_object_unref (stream); }
static void bg_pictures_source_finalize (GObject *object) { BgPicturesSource *bg_source = BG_PICTURES_SOURCE (object); g_clear_object (&bg_source->priv->thumb_factory); g_clear_pointer (&bg_source->priv->known_items, g_hash_table_destroy); g_clear_object (&bg_source->priv->picture_dir_monitor); g_clear_object (&bg_source->priv->cache_dir_monitor); G_OBJECT_CLASS (bg_pictures_source_parent_class)->finalize (object); }
static void bg_pictures_source_dispose (GObject *object) { BgPicturesSourcePrivate *priv = BG_PICTURES_SOURCE (object)->priv; if (priv->cancellable) { g_cancellable_cancel (priv->cancellable); g_clear_object (&priv->cancellable); } g_clear_object (&priv->grl_miner); g_clear_object (&priv->thumb_factory); G_OBJECT_CLASS (bg_pictures_source_parent_class)->dispose (object); }
static void file_info_async_ready (GObject *source, GAsyncResult *res, gpointer user_data) { BgPicturesSource *bg_source; GList *files, *l; GError *err = NULL; GFile *parent; files = g_file_enumerator_next_files_finish (G_FILE_ENUMERATOR (source), res, &err); if (err) { if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("Could not get pictures file information: %s", err->message); g_error_free (err); g_list_foreach (files, (GFunc) g_object_unref, NULL); g_list_free (files); return; } bg_source = BG_PICTURES_SOURCE (user_data); parent = g_file_enumerator_get_container (G_FILE_ENUMERATOR (source)); files = g_list_sort (files, file_sort_func); /* iterate over the available files */ for (l = files; l; l = g_list_next (l)) { GFileInfo *info = l->data; GFile *file; file = g_file_get_child (parent, g_file_info_get_name (info)); add_single_file_from_info (bg_source, file, info, NULL); } g_list_foreach (files, (GFunc) g_object_unref, NULL); g_list_free (files); }
static void bg_pictures_source_finalize (GObject *object) { BgPicturesSource *bg_source = BG_PICTURES_SOURCE (object); if (bg_source->priv->thumb_factory) { g_object_unref (bg_source->priv->thumb_factory); bg_source->priv->thumb_factory = NULL; } if (bg_source->priv->known_items) { g_hash_table_destroy (bg_source->priv->known_items); bg_source->priv->known_items = NULL; } G_OBJECT_CLASS (bg_pictures_source_parent_class)->finalize (object); }
static void bg_pictures_source_dispose (GObject *object) { BgPicturesSourcePrivate *priv = BG_PICTURES_SOURCE (object)->priv; if (priv->cancellable) { g_cancellable_cancel (priv->cancellable); g_object_unref (priv->cancellable); priv->cancellable = NULL; } if (priv->thumb_factory) { g_object_unref (priv->thumb_factory); priv->thumb_factory = NULL; } G_OBJECT_CLASS (bg_pictures_source_parent_class)->dispose (object); }
static void picture_copied_for_read (GObject *source_object, GAsyncResult *res, gpointer user_data) { BgPicturesSource *bg_source; CcBackgroundItem *item; GError *error = NULL; GFile *thumbnail_file = G_FILE (source_object); GFile *native_file; if (!g_file_copy_finish (thumbnail_file, res, &error)) { if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) goto out; else if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS)) { gchar *uri; uri = g_file_get_uri (thumbnail_file); g_warning ("Failed to download '%s': %s", uri, error->message); g_free (uri); goto out; } } bg_source = BG_PICTURES_SOURCE (user_data); native_file = g_object_get_data (G_OBJECT (thumbnail_file), "native-file"); item = g_object_get_data (G_OBJECT (thumbnail_file), "item"); g_object_set_data_full (G_OBJECT (native_file), "item", g_object_ref (item), g_object_unref); g_file_read_async (native_file, G_PRIORITY_DEFAULT, bg_source->priv->cancellable, picture_opened_for_read, bg_source); out: g_clear_error (&error); }
static void picture_scaled (GObject *source_object, GAsyncResult *res, gpointer user_data) { BgPicturesSource *bg_source; CcBackgroundItem *item; GError *error = NULL; GdkPixbuf *pixbuf = NULL; const char *software; const char *uri; GtkTreeIter iter; GtkTreePath *path; GtkTreeRowReference *row_ref; GtkListStore *store; cairo_surface_t *surface = NULL; int scale_factor; item = g_object_get_data (source_object, "item"); pixbuf = gdk_pixbuf_new_from_stream_finish (res, &error); if (pixbuf == NULL) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { g_warning ("Failed to load image: %s", error->message); remove_placeholder (BG_PICTURES_SOURCE (user_data), item); } g_error_free (error); goto out; } /* since we were not cancelled, we can now cast user_data * back to BgPicturesSource. */ bg_source = BG_PICTURES_SOURCE (user_data); store = bg_source_get_liststore (BG_SOURCE (bg_source)); uri = cc_background_item_get_uri (item); if (uri == NULL) uri = cc_background_item_get_source_url (item); /* Ignore screenshots */ software = gdk_pixbuf_get_option (pixbuf, "tEXt::Software"); if (software != NULL && g_str_equal (software, "gnome-screenshot")) { g_debug ("Ignored URL '%s' as it's a screenshot from gnome-screenshot", uri); remove_placeholder (BG_PICTURES_SOURCE (user_data), item); goto out; } scale_factor = bg_source_get_scale_factor (BG_SOURCE (bg_source)); surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale_factor, NULL); cc_background_item_load (item, NULL); row_ref = g_object_get_data (G_OBJECT (item), "row-ref"); if (row_ref == NULL) { /* insert the item into the liststore if it did not exist */ gtk_list_store_insert_with_values (store, NULL, -1, 0, surface, 1, item, -1); } else { path = gtk_tree_row_reference_get_path (row_ref); if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path)) { /* otherwise update the thumbnail */ gtk_list_store_set (store, &iter, 0, surface, -1); } } g_hash_table_insert (bg_source->priv->known_items, bg_pictures_source_get_unique_filename (uri), GINT_TO_POINTER (TRUE)); out: g_clear_pointer (&surface, (GDestroyNotify) cairo_surface_destroy); g_clear_object (&pixbuf); }
static void picture_scaled (GObject *source_object, GAsyncResult *res, gpointer user_data) { BgPicturesSource *bg_source; CcBackgroundItem *item; GError *error = NULL; GdkPixbuf *pixbuf; const char *source_url; const char *software; GtkTreeIter iter; GtkListStore *store; pixbuf = gdk_pixbuf_new_from_stream_finish (res, &error); if (pixbuf == NULL) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("Failed to load image: %s", error->message); g_error_free (error); return; } /* since we were not cancelled, we can now cast user_data * back to BgPicturesSource. */ bg_source = BG_PICTURES_SOURCE (user_data); store = bg_source_get_liststore (BG_SOURCE (bg_source)); item = g_object_get_data (source_object, "item"); gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (store), 1, (GtkTreeIterCompareFunc)sort_func, bg_source, NULL); gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), 1, GTK_SORT_ASCENDING); /* Ignore screenshots */ software = gdk_pixbuf_get_option (pixbuf, "tEXt::Software"); if (software != NULL && g_str_equal (software, "gnome-screenshot")) { g_debug ("Ignored URL '%s' as it's a screenshot from gnome-screenshot", cc_background_item_get_uri (item)); g_object_unref (pixbuf); g_object_unref (item); return; } cc_background_item_load (item, NULL); /* insert the item into the liststore */ gtk_list_store_insert_with_values (store, &iter, 0, 0, pixbuf, 1, item, -1); source_url = cc_background_item_get_source_url (item); if (source_url != NULL) { g_hash_table_insert (bg_source->priv->known_items, bg_pictures_source_get_unique_filename (source_url), GINT_TO_POINTER (TRUE)); } else { char *cache_path; GFile *file, *parent, *dir; cache_path = bg_pictures_source_get_cache_path (); dir = g_file_new_for_path (cache_path); g_free (cache_path); file = g_file_new_for_uri (cc_background_item_get_uri (item)); parent = g_file_get_parent (file); if (g_file_equal (parent, dir)) { char *basename; basename = g_file_get_basename (file); g_hash_table_insert (bg_source->priv->known_items, basename, GINT_TO_POINTER (TRUE)); } g_object_unref (file); g_object_unref (parent); } g_object_unref (pixbuf); }
static void picture_scaled (GObject *source_object, GAsyncResult *res, gpointer user_data) { BgPicturesSource *bg_source = BG_PICTURES_SOURCE (user_data); CcBackgroundItem *item; GError *error = NULL; GdkPixbuf *pixbuf; const char *source_url; GtkTreeIter iter; GtkListStore *store; store = bg_source_get_liststore (BG_SOURCE (bg_source)); item = g_object_get_data (source_object, "item"); pixbuf = gdk_pixbuf_new_from_stream_finish (res, &error); if (pixbuf == NULL) { g_warning ("Failed to load image: %s", error->message); g_error_free (error); g_object_unref (item); return; } /* insert the item into the liststore */ gtk_list_store_insert_with_values (store, &iter, 0, 0, pixbuf, 1, item, -1); source_url = cc_background_item_get_source_url (item); if (source_url != NULL) { g_hash_table_insert (bg_source->priv->known_items, bg_pictures_source_get_unique_filename (source_url), GINT_TO_POINTER (TRUE)); } else { char *cache_path; GFile *file, *parent, *dir; cache_path = bg_pictures_source_get_cache_path (); dir = g_file_new_for_path (cache_path); g_free (cache_path); file = g_file_new_for_uri (cc_background_item_get_uri (item)); parent = g_file_get_parent (file); if (g_file_equal (parent, dir)) { char *basename; basename = g_file_get_basename (file); g_hash_table_insert (bg_source->priv->known_items, basename, GINT_TO_POINTER (TRUE)); } g_object_unref (file); g_object_unref (parent); } g_object_unref (pixbuf); }