/* * Copyright (C) 2007 Ross Burton * * Author: Ross Burton * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H # include #endif /* HAVE_CONFIG_H */ #include #include #include "egg-pixbuf-thumbnail.h" #include "thumbnailer.h" static GStaticMutex thumbnail_queue_lock = G_STATIC_MUTEX_INIT; static guint thumbnail_idle_id; static GAsyncQueue *thumbnail_queue; static GThreadPool *thumbnailer_pool; static gboolean set_thumbnail (gpointer user_data) { ThumbnailData *data; GtkListStore *store; g_return_val_if_fail (GTK_IS_LIST_STORE (user_data), FALSE); store = user_data; /* TODO: can I lock this any later? I don't want to race between this loop ending and the handler being re-registered. */ g_static_mutex_lock (&thumbnail_queue_lock); while ((data = g_async_queue_try_pop (thumbnail_queue)) != NULL) { if (data->thumb) { gtk_list_store_set (store, &data->iter, COL_THUMB, data->thumb, -1); gdk_pixbuf_unref (data->thumb); } g_object_unref (data->file); g_slice_free (ThumbnailData, data); } thumbnail_idle_id = 0; g_static_mutex_unlock (&thumbnail_queue_lock); return FALSE; } /* TODO: integrate gvfs into EggPixbufThumbnail */ static void thumbnail_thread (gpointer thread_data, gpointer user_data) { ThumbnailData *data = thread_data; char *path; g_assert (data); path = g_file_get_path (data->file); /* TODO: if thumbnail doesn't exist, attempt to read JPEG thumbnail with libexif */ data->thumb = egg_pixbuf_get_thumbnail_for_file (path, EGG_PIXBUF_THUMBNAIL_NORMAL, NULL); g_free (path); g_async_queue_push (thumbnail_queue, data); g_static_mutex_lock (&thumbnail_queue_lock); if (thumbnail_idle_id == 0) { thumbnail_idle_id = g_timeout_add (50, set_thumbnail, user_data); } g_static_mutex_unlock (&thumbnail_queue_lock); } void thumbnailer_push (ThumbnailData *data) { g_return_if_fail (data != NULL); g_thread_pool_push (thumbnailer_pool, data, NULL); } void thumbnailer_init (KatachiImageStore *liststore) { g_return_if_fail (KATACHI_IS_IMAGE_STORE (liststore)); thumbnail_idle_id = 0; thumbnailer_pool = g_thread_pool_new (thumbnail_thread, liststore, 4, FALSE, NULL); thumbnail_queue = g_async_queue_new (); }